// Round-trip verification tool: opens a pack read-only, reads every entry via
// the same CEterPack::Get() path the game engine uses, and byte-compares it
// against the corresponding file under a source folder.
//
// Usage: PackVerify.exe <packFolder> <dbname> <sourceFolder>
//   e.g. PackVerify.exe "Y:\scratch\pack" root "Y:\Metin2Dev\Exec_Client\Eternexus\root"

#include <windows.h>
#include <cstdio>
#include <string>
#include <vector>
#include <fstream>

#include "../EterPack/EterPack.h"

int main(int argc, char** argv)
{
	if (argc < 4)
	{
		fprintf(stderr, "Usage: %s <packFolder> <dbname> <sourceFolder>\n", argv[0]);
		return 1;
	}

	const char* pathName = argv[1];
	const char* dbname = argv[2];
	std::string sourceFolder = argv[3];

	if (!SetCurrentDirectoryA(pathName))
	{
		fprintf(stderr, "FAILED to chdir to '%s'\n", pathName);
		return 4;
	}

	CEterFileDict dict;
	CEterPack pack;

	if (!pack.Create(dict, dbname, "", true))
	{
		fprintf(stderr, "FAILED to open pack '%s' in '%s'\n", dbname, pathName);
		return 2;
	}

	std::vector<std::string> names;
	if (!pack.GetNames(&names))
	{
		fprintf(stderr, "FAILED GetNames\n");
		return 3;
	}

	long okCount = 0, mismatchCount = 0, missingSrcCount = 0, getFailCount = 0;

	for (auto& name : names)
	{
		std::string srcPath = sourceFolder + "\\" + name;
		for (auto& c : srcPath) if (c == '/') c = '\\';

		std::ifstream srcFile(srcPath, std::ios::binary | std::ios::ate);
		if (!srcFile)
		{
			fprintf(stderr, "MISSING SOURCE: %s (expected at %s)\n", name.c_str(), srcPath.c_str());
			++missingSrcCount;
			continue;
		}

		std::streamsize srcSize = srcFile.tellg();
		srcFile.seekg(0);
		std::vector<char> srcData(srcSize);
		srcFile.read(srcData.data(), srcSize);

		CMappedFile mappedFile;
		LPCVOID packData = NULL;

		if (!pack.Get(mappedFile, name.c_str(), &packData))
		{
			fprintf(stderr, "Get() FAILED: %s\n", name.c_str());
			++getFailCount;
			continue;
		}

		DWORD packSize = mappedFile.Size();

		if ((std::streamsize)packSize != srcSize || memcmp(packData, srcData.data(), srcSize) != 0)
		{
			fprintf(stderr, "MISMATCH: %s (src %lld bytes, pack %lu bytes)\n", name.c_str(), (long long)srcSize, packSize);
			++mismatchCount;
			continue;
		}

		++okCount;
	}

	printf("Verified %ld entries: %ld OK, %ld mismatched, %ld missing-source, %ld get-failed\n",
		(long)names.size(), okCount, mismatchCount, missingSrcCount, getFailCount);

	return (mismatchCount > 0 || getFailCount > 0) ? 5 : 0;
}
