/*
 * Copyright © 2009-2020 Frictional Games
 *
 * This file is part of Amnesia: The Dark Descent.
 *
 * Amnesia: The Dark Descent is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * Amnesia: The Dark Descent is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Amnesia: The Dark Descent.  If not, see <https://www.gnu.org/licenses/>.
 */

#include "hpl.h"
#include "impl/tinyXML/tinyxml.h"
#include "impl/XmlDocumentTiny.h"

using namespace hpl;

//--------------------------------------------------------------------------------

tString gsAppName;
tString gsLocalPath;
tString gsProjectIncludePath;
tString gsOutHeaderPath;
tString gsOutSourcePath;
tString gsBuildId;

//--------------------------------------------------------------------------------

bool ParseInputFile(const tString& asPath);

bool WriteVersionFiles();

//--------------------------------------------------------------------------------

int hplMain(const tString& asCommandLine)
{
	return 0;
}

//--------------------------------------------------------------------------------

int main(int argc, char* argv[])
{
	if(argc<2)
	{
		printf("Usage: %s InputFile\n", cString::GetFileName(argv[0]).c_str());
		return -1;
	}

	printf("%ws\n", cPlatform::GetWorkingDir().c_str());

	/////////////////////////////////////////////////////////////////////
	// Parse input
	if(ParseInputFile(tString(argv[1]))==false)
		return -1;

	cDate date = cPlatform::GetDate();
	gsBuildId = cString::ToString(date.year) + cString::ToString(date.month+1,2) + cString::ToString(date.month_day,2) +
					cString::ToString(date.hours,2) + cString::ToString(date.minutes,2) + cString::ToString(date.seconds,2);

	if(WriteVersionFiles()==false)
		return -1;

	return 0;
}

//--------------------------------------------------------------------------------

bool ParseInputFile(const tString& asPath)
{
	FILE* pFile = cPlatform::OpenFile(cString::To16Char(asPath), _W("r"));

	if(pFile==NULL)
		return false;

	tString separators[] = { " " };
	char buffer[256];
	while(fgets(buffer, 256, pFile)!=NULL)
	{
		size_t lLineLength = strlen(buffer);
		if(buffer[lLineLength-1]=='\n')
			buffer[lLineLength-1]='\0';

		tString sLine = tString(buffer);

		tStringVec vStringsInLine;
		vStringsInLine = cString::GetStringVec(sLine, vStringsInLine, separators);
		if(vStringsInLine.size()<2)
			return false;

		tString& sString = vStringsInLine[0];
		if(sString=="AppName")
			gsAppName = vStringsInLine[1];
		else if(sString=="LocalPath")
			gsLocalPath = vStringsInLine[1];
		else if(sString=="ProjectIncludePath")
			gsProjectIncludePath = vStringsInLine[1];
		else if(sString=="OutHeaderPath")
			gsOutHeaderPath = vStringsInLine[1];
		else if(sString=="OutSourcePath")
			gsOutSourcePath = vStringsInLine[1];
	}

	fclose(pFile);

	if(gsProjectIncludePath=="")
	{
		if(gsOutHeaderPath=="")
			gsOutHeaderPath = gsOutSourcePath;
	}
	else if(gsOutSourcePath=="")
		gsOutSourcePath = gsOutHeaderPath;

	if(gsAppName=="" || gsOutHeaderPath=="" || gsOutSourcePath=="")
		return false;

	return true;
}

//--------------------------------------------------------------------------------

bool WriteVersionFiles()
{
	tString sHeader;
	tString sBody;
	tString sFooter;

	tString sName = "BuildID_"+gsAppName;
	tWString sFileName = cString::To16Char(sName);

	sHeader = "//////////////////////////////////////////////////\n";
	sHeader +="// File autogenerated by buildcounter\n";
	sHeader +="// Do not hand edit! (preferably)\n";
	sHeader +="//////////////////////////////////////////////////\n";

	FILE* pOutputFile = NULL;

	////////////////////////////////////////////////////
	// Header file
	tWString sFile = cString::AddSlashAtEndW(cString::To16Char(gsLocalPath)) +
					 cString::AddSlashAtEndW(cString::To16Char(gsProjectIncludePath)) +
					 cString::AddSlashAtEndW(cString::To16Char(gsOutHeaderPath)) +
					 sFileName + _W(".h");
	printf("Looking for header file %ws\n", sFile.c_str());
	if(cPlatform::FileExists(sFile)==false)
	{
		pOutputFile = cPlatform::OpenFile(sFile, _W("w+"));
		if(pOutputFile==NULL)
			return false;

		tString sHeaderName = cString::ToUpperCase(sName) + "_H";

		sBody = "\n";
		sBody += "#ifndef " + sHeaderName + "\n";
		sBody += "#define " + sHeaderName + "\n";
		sBody += "\n";
		sBody += "const char* GetBuildID_" + gsAppName + "();\n";
		sBody += "\n";

		sFooter = "\n#endif //"+sHeaderName+"\n";

		fprintf(pOutputFile, sHeader.c_str());
		fprintf(pOutputFile, sBody.c_str());
		fprintf(pOutputFile, sFooter.c_str());

		fclose(pOutputFile);

		printf("Written updated output file %ws for app %s\n", sFile.c_str(), gsAppName.c_str());
	}

	////////////////////////////////////////////////////
	// Source file
	{
		sFile = cString::AddSlashAtEndW(cString::To16Char(gsLocalPath)) +
				cString::AddSlashAtEndW(cString::To16Char(gsOutSourcePath)) +
				sFileName + _W("_") +
				cString::To16Char(cPlatform::GetPlatformName()) + _W(".cpp");
		pOutputFile = cPlatform::OpenFile(sFile, _W("w+"));
		if(pOutputFile==NULL)
			return false;

		sBody = "#include \"" + cString::AddSlashAtEnd(gsOutHeaderPath) + sName + ".h\"\n";
		sBody +="\n";
		sBody += "static char gsBuildID[16] = \"" + gsBuildId + "\";\n";

		sBody +="\n";
		sBody += "const char* GetBuildID_" + gsAppName + "()\n";
		sBody +="{\n";
		sBody +="\treturn gsBuildID;\n";
		sBody +="}\n";
		sBody += "\n";

		fprintf(pOutputFile, sHeader.c_str());
		fprintf(pOutputFile, sBody.c_str());

		fclose(pOutputFile);

		printf("Written updated output file %ws for app %s\n", sFile.c_str(), gsAppName.c_str());
	}

	return true;
}

//--------------------------------------------------------------------------------
