/*
 * MoltenVKShaderConverterTool.cpp
 *
 * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "MoltenVKShaderConverterTool.h"
#include "FileSupport.h"
#include "DirectorySupport.h"
#include "GLSLToSPIRVConverter.h"
#include "SPIRVToMSLConverter.h"

using namespace std;
using namespace mvk;


/** The default list of vertex file extensions. */
static const char* _defaultVertexShaderExtns = "vs vsh vert vertex";

/** The default list of fragment file extensions. */
static const char* _defaultFragShaderExtns = "fs fsh frag fragment";

/** The default list of compute file extensions. */
static const char* _defaultCompShaderExtns = "cp cmp comp compute kn kl krn kern kernel";

/** The default list of SPIR-V file extensions. */
static const char* _defaultSPIRVShaderExtns = "spv spirv";


#pragma mark -
#pragma mark MoltenVKShaderConverterTool


int MoltenVKShaderConverterTool::run() {
	bool success = false;
	if ( !_directoryPath.empty() ) {
		string errMsg;
		success = iterateDirectory(_directoryPath, *this, _shouldUseDirectoryRecursion, errMsg);
		if ( !success ) { log(errMsg.data()); }
	} else {
		if (_shouldReadGLSL) {
			success = convertGLSL(_glslInFilePath, _spvOutFilePath, _mslOutFilePath, _shaderStage);
		} else if (_shouldReadSPIRV) {
			success = convertSPIRV(_spvInFilePath, _mslOutFilePath);
		} else {
			showUsage();
		}
	}
	return success ? EXIT_SUCCESS : EXIT_FAILURE;
}

bool MoltenVKShaderConverterTool::processFile(string filePath) {
	string absPath = absolutePath(filePath);
	string emptyPath;

	string pathExtn = pathExtension(absPath);
	if (_shouldReadGLSL && isGLSLFileExtension(pathExtn)) {
		convertGLSL(absPath, emptyPath, emptyPath, kMVKShaderStageAuto);
	} else if (_shouldReadSPIRV && isSPIRVFileExtension(pathExtn)) {
		convertSPIRV(absPath, emptyPath);
	}

	return false;
}

/**
 * Read GLSL code from a GLSL file, convert to SPIR-V, and optionally MSL,
 * and write the SPIR-V and/or MSL code to files.
 */
bool MoltenVKShaderConverterTool::convertGLSL(string& glslInFile,
											string& spvOutFile,
											string& mslOutFile,
											MVKShaderStage shaderStage) {
	string path;
	vector<char> fileContents;
	string glslCode;
	string errMsg;

	// Read the GLSL
	if (glslInFile.empty()) {
		log("The GLSL file to read from was not specified");
		return false;
	}

	path = glslInFile;
	if (readFile(path, fileContents, errMsg)) {
		string logMsg = "Read GLSL from file: " + lastPathComponent(path);
		log(logMsg.data());
	} else {
		errMsg = "Could not read GLSL file. " + errMsg;
		log(errMsg.data());
		return false;
	}
	glslCode.append(fileContents.begin(), fileContents.end());

	if (shaderStage == kMVKShaderStageAuto) {
		string pathExtn = pathExtension(glslInFile);
		shaderStage = shaderStageFromFileExtension(pathExtn);
	}
	if (shaderStage == kMVKShaderStageAuto) {
		errMsg = "Could not determine shader type from GLSL file: " + absolutePath(path);
		log(errMsg.data());
		return false;
	}

	// Convert GLSL to SPIR-V
	GLSLToSPIRVConverter glslConverter;
	glslConverter.setGLSL(glslCode);
	if (glslConverter.convert(shaderStage, _shouldLogConversions, _shouldLogConversions)) {
		if (_shouldLogConversions) { log(glslConverter.getResultLog().data()); }
	} else {
		string logMsg = "Could not convert GLSL in file: " + absolutePath(path);
		log(logMsg.data());
		log(glslConverter.getResultLog().data());
		return false;
	}

	const vector<uint32_t>& spv = glslConverter.getSPIRV();

	// Write the SPIR-V code to a file.
	// If no file has been supplied, create one from the GLSL file name.
	if (_shouldWriteSPIRV) {
		path = spvOutFile;
		if (path.empty()) { path = pathWithExtension(glslInFile, "spv", _shouldIncludeOrigPathExtn, _origPathExtnSep); }

		spirvToBytes(spv, fileContents);
		if (writeFile(path, fileContents, errMsg)) {
			string logMsg = "Saved SPIR-V to file: " + lastPathComponent(path);
			log(logMsg.data());
		} else {
			errMsg = "Could not write SPIR-V file. " + errMsg;
			log(errMsg.data());
			return false;
		}
	}

	return convertSPIRV(spv, glslInFile, mslOutFile, false);
}

/** Read SPIR-V code from a SPIR-V file, convert to MSL, and write the MSL code to files. */
bool MoltenVKShaderConverterTool::convertSPIRV(string& spvInFile,
											 string& mslOutFile) {
	string path;
	vector<char> fileContents;
	vector<uint32_t> spv;
	string errMsg;

	// Read the SPIRV
	if (spvInFile.empty()) {
		log("The SPIR-V file to read from was not specified");
		return false;
	}

	path = spvInFile;
	if (readFile(path, fileContents, errMsg)) {
		string logMsg = "Read SPIR-V from file: " + lastPathComponent(path);
		log(logMsg.data());
	} else {
		errMsg = "Could not read SPIR-V file. " + errMsg;
		log(errMsg.data());
		return false;
	}
	bytesToSPIRV(fileContents, spv);

	return convertSPIRV(spv, spvInFile, mslOutFile, _shouldLogConversions);
}

/** Read SPIR-V code from an array, convert to MSL, and write the MSL code to files. */
bool MoltenVKShaderConverterTool::convertSPIRV(const vector<uint32_t>& spv,
											 string& inFile,
											 string& mslOutFile,
											 bool shouldLogSPV) {
	if ( !_shouldWriteMSL ) { return true; }

	// Derive the context under which conversion will occur
	SPIRVToMSLConverterContext mslContext;
	mslContext.options.shouldFlipVertexY = _shouldFlipVertexY;

	SPIRVToMSLConverter spvConverter;
	spvConverter.setSPIRV(spv);
	if (spvConverter.convert(mslContext, shouldLogSPV, _shouldLogConversions, (_shouldLogConversions && shouldLogSPV))) {
		if (_shouldLogConversions) { log(spvConverter.getResultLog().data()); }
	} else {
		string errMsg = "Could not convert SPIR-V in file: " + absolutePath(inFile);
		log(errMsg.data());
		log(spvConverter.getResultLog().data());
		return false;
	}

	// Write the MSL to file
	string path = mslOutFile;
	if (mslOutFile.empty()) { path = pathWithExtension(inFile, "metal", _shouldIncludeOrigPathExtn, _origPathExtnSep); }
	const string& msl = spvConverter.getMSL();
	vector<char> fileContents;
	fileContents.insert(fileContents.end(), msl.begin(), msl.end());
	string errMsg;
	if (writeFile(path, fileContents, errMsg)) {
		string logMsg = "Saved MSL to file: " + lastPathComponent(path);
		log(logMsg.data());
		return true;
	} else {
		errMsg = "Could not write MSL file. " + errMsg;
		log(errMsg.data());
		return false;
	}
}

MVKShaderStage MoltenVKShaderConverterTool::shaderStageFromFileExtension(string& pathExtension) {
    for (auto& fx : _glslVtxFileExtns) { if (fx == pathExtension) { return kMVKShaderStageVertex; } }
    for (auto& fx : _glslFragFileExtns) { if (fx == pathExtension) { return kMVKShaderStageFragment; } }
    for (auto& fx : _glslCompFileExtns) { if (fx == pathExtension) { return kMVKShaderStageCompute; } }
	return kMVKShaderStageAuto;
}

bool MoltenVKShaderConverterTool::isGLSLFileExtension(string& pathExtension) {
    for (auto& fx : _glslVtxFileExtns) { if (fx == pathExtension) { return true; } }
    for (auto& fx : _glslFragFileExtns) { if (fx == pathExtension) { return true; } }
    for (auto& fx : _glslCompFileExtns) { if (fx == pathExtension) { return true; } }
	return false;
}

bool MoltenVKShaderConverterTool::isSPIRVFileExtension(string& pathExtension) {
    for (auto& fx : _spvFileExtns) { if (fx == pathExtension) { return true; } }
	return false;
}

/** Log the specified message to the console. */
void MoltenVKShaderConverterTool::log(const char* logMsg) { printf("%s\n", logMsg); }

/** Display usage information about this application on the console. */
void MoltenVKShaderConverterTool::showUsage() {
	string line = "\n\e[1m" + _processName + "\e[0m converts OpenGL Shading Language (GLSL) source code to";
	log((const char*)line.c_str());
	log("SPIR-V code, and/or to Metal Shading Language (MSL) source code, or converts");
	log("SPIR-V code to Metal Shading Language source code.");
	log("\nTo convert a single GLSL or SPIR-V file, include a file reference with the -gi");
	log("or -si option, respectively. To convert an entire directory of shader files,");
	log("use the -d option, along with the -gi or -si option. When using the -d option,");
	log("any file name supplied with the -gi or -si option will be ignored.");
    log("\nUse the -so or -mo option to indicate the desired type of output");
    log("(SPIR-V or MSL, respectively).");
	log("\nUsage:");
	log("  -d [\"dirPath\"]     - Path to a directory containing GLSL shader source code");
	log("                       files. The dirPath may be omitted to use the current");
	log("                       working directory.");
	log("  -r                 - (when using -d) Process directories recursively.");
	log("  -gi [\"glslInFile\"] - Indicates that GLSL shader code should be input.");
	log("                       The optional path parameter specifies the path to a");
	log("                       single file containing GLSL source code to be converted.");
	log("                       When using the -d option, the path parameter is ignored.");
	log("  -si [\"spvInFile\"]  - Indicates that SPIR-V shader code should be input.");
	log("                       The optional path parameter specifies the path to a");
	log("                       single file containing SPIR-V code to be converted.");
	log("                       When using the -d option, the path parameter is ignored.");
	log("  -so [\"spvOutFile\"] - Indicates that SPIR-V shader code should be output.");
	log("                       The optional path parameter specifies the path to a single");
	log("                       file to contain the SPIR-V code. When using the -d option,");
	log("                       the path parameter is ignored.");
	log("  -mo [\"mslOutFile\"] - Indicates that MSL shader source code should be output.");
	log("                       The optional path parameter specifies the path to a single");
	log("                       file to contain the MSL code. When using the -d option,");
	log("                       the path parameter is ignored.");
	log("  -t shaderType      - Shader type: vertex or fragment. Must be one of v, f, or c.");
	log("                       May be omitted to auto-detect.");
	log("  -c                 - Combine the GLSL and converted Metal Shader source code");
	log("                       into a single ouput file.");
	log("  -Iv                - Disable inversion of the vertex coordinate Y-axis");
    log("                       (default is to invert vertex coordinates).");
	log("  -xs \"xtnSep\"       - Separator to use when including file extension of original");
	log("                       code file name in derived converted code file name.");
	log("                       Default is \"_\" (myshdr.vsh -> myshdr_vsh.metal).");
	log("  -XS                - Disable including file extension of original code");
	log("                       file name in derived converted code file name");
	log("                       (myshdr.vsh -> myshdr.metal).");
	log("  -vx \"fileExtns\"    - List of GLSL vertex shader file extensions.");
	log("                       May be omitted for defaults (\"vs vsh vert vertex\").");
	log("  -fx \"fileExtns\"    - List of GLSL fragment shader file extensions.");
	log("                       May be omitted for defaults (\"fs fsh frag fragment\").");
    log("  -cx \"fileExtns\"    - List of GLSL compute shader file extensions.");
    log("                       May be omitted for defaults (\"cp cmp comp compute kn kl krn kern kernel\").");
	log("  -sx \"fileExtns\"    - List of SPIR-V shader file extensions.");
	log("                       May be omitted for defaults (\"spv spirv\").");
	log("  -l                 - Log the conversion results to the console (to aid debugging).");
	log("");
}


#pragma mark Construction

MoltenVKShaderConverterTool::MoltenVKShaderConverterTool(int argc, const char* argv[]) {
	extractTokens(_defaultVertexShaderExtns, _glslVtxFileExtns);
	extractTokens(_defaultFragShaderExtns, _glslFragFileExtns);
    extractTokens(_defaultCompShaderExtns, _glslCompFileExtns);
	extractTokens(_defaultSPIRVShaderExtns, _spvFileExtns);
	_origPathExtnSep = "_";
	_shaderStage = kMVKShaderStageAuto;
	_isActive = false;
	_shouldUseDirectoryRecursion = false;
	_shouldReadGLSL = false;
	_shouldReadSPIRV = false;
	_shouldWriteSPIRV = false;
	_shouldWriteMSL = false;
	_shouldCombineGLSLAndMSL = false;
    _shouldFlipVertexY = true;
	_shouldIncludeOrigPathExtn = true;
	_shouldLogConversions = false;

	_isActive = parseArgs(argc, argv);
	if ( !_isActive ) { showUsage(); }
}

bool MoltenVKShaderConverterTool::parseArgs(int argc, const char* argv[]) {
	if (argc == 0) { return false; }

	string execPath(argv[0]);
	_processName = lastPathComponent(execPath);

	for (int argIdx = 1; argIdx < argc; argIdx++) {
		string arg = argv[argIdx];

		if ( !isOptionArg(arg) ) { return false; }

		if (equal(arg, "-d", false)) {
			int optIdx = argIdx;
			argIdx = optionParam(_directoryPath, argIdx, argc, argv);
			if (argIdx == optIdx) { return false; }
			_directoryPath = absolutePath(_directoryPath);
			continue;
		}

		if(equal(arg, "-r", true)) {
			_shouldUseDirectoryRecursion = true;
			continue;
		}

		if (equal(arg, "-gi", true)) {
			_shouldReadGLSL = true;
			argIdx = optionParam(_glslInFilePath, argIdx, argc, argv);
			continue;
		}

		if (equal(arg, "-si", true)) {
			_shouldReadSPIRV = true;
			argIdx = optionParam(_spvInFilePath, argIdx, argc, argv);
			continue;
		}

		if (equal(arg, "-so", true)) {
			_shouldWriteSPIRV = true;
			argIdx = optionParam(_spvOutFilePath, argIdx, argc, argv);
			continue;
		}

		if (equal(arg, "-mo", true)) {
			_shouldWriteMSL = true;
			argIdx = optionParam(_mslOutFilePath, argIdx, argc, argv);
			continue;
		}

		if (equal(arg, "-t", true)) {
			int optIdx = argIdx;
			string shdrTypeStr;
			argIdx = optionParam(shdrTypeStr, argIdx, argc, argv);
			if (argIdx == optIdx || shdrTypeStr.length() == 0) { return false; }

			switch (shdrTypeStr.front()) {
				case 'v':
					_shaderStage = kMVKShaderStageVertex;
					break;
				case 'f':
					_shaderStage = kMVKShaderStageFragment;
					break;
				case 'c':
					_shaderStage = kMVKShaderStageCompute;
					break;
				default:
					break;
			}
			continue;
		}

		if(equal(arg, "-c", true)) {
			_shouldCombineGLSLAndMSL = true;
			continue;
		}

        if(equal(arg, "-Iv", true)) {
            _shouldFlipVertexY = false;
            continue;
        }

		if (equal(arg, "-xs", true)) {
			_shouldIncludeOrigPathExtn = true;
			argIdx++;
			if (argIdx < argc) { _origPathExtnSep = argv[argIdx]; }
			continue;
		}

		if(equal(arg, "-XS", true)) {
			_shouldIncludeOrigPathExtn = false;
			continue;
		}

		if (equal(arg, "-vx", true)) {
			int optIdx = argIdx;
			string shdrExtnStr;
			argIdx = optionParam(shdrExtnStr, argIdx, argc, argv);
			if (argIdx == optIdx || shdrExtnStr.length() == 0) { return false; }
			extractTokens(shdrExtnStr, _glslVtxFileExtns);
			continue;
		}

		if (equal(arg, "-fx", true)) {
			int optIdx = argIdx;
			string shdrExtnStr;
			argIdx = optionParam(shdrExtnStr, argIdx, argc, argv);
			if (argIdx == optIdx || shdrExtnStr.length() == 0) { return false; }
			extractTokens(shdrExtnStr, _glslFragFileExtns);
			continue;
		}

        if (equal(arg, "-cx", true)) {
            int optIdx = argIdx;
            string shdrExtnStr;
            argIdx = optionParam(shdrExtnStr, argIdx, argc, argv);
            if (argIdx == optIdx || shdrExtnStr.length() == 0) { return false; }
            extractTokens(shdrExtnStr, _glslCompFileExtns);
            continue;
        }

		if (equal(arg, "-sx", true)) {
			int optIdx = argIdx;
			string shdrExtnStr;
			argIdx = optionParam(shdrExtnStr, argIdx, argc, argv);
			if (argIdx == optIdx || shdrExtnStr.length() == 0) { return false; }
			extractTokens(shdrExtnStr, _spvFileExtns);
			continue;
		}

		if(equal(arg, "-l", true)) {
			_shouldLogConversions = true;
			continue;
		}

	}

	return true;
}

/** Returns whether the specified command line arg is an option arg. */
bool MoltenVKShaderConverterTool::isOptionArg(string& arg) {
	return (arg.length() > 1 && arg.front() == '-');
}

/** 
 * Sets the contents of the specified string to the parameter part of the option at the 
 * specified arg index, and increments and returns the option index. If no parameter was
 * provided for the option, the string will be set to an empty string, and the returned
 * index will be the same as the specified index.
 */
int MoltenVKShaderConverterTool::optionParam(string& optionParamResult,
										   int optionArgIndex,
										   int argc,
										   const char* argv[]) {
	int optParamIdx = optionArgIndex + 1;
	if (optParamIdx < argc) {
		string arg(argv[optParamIdx]);
		if ( !isOptionArg(arg) ) {
			optionParamResult = arg;
			return optParamIdx;
		}
	}
	optionParamResult.clear();
	return optionArgIndex;
}


#pragma mark -
#pragma mark Support functions

/** Template function for tokenizing the components of a string into a vector. */
template <typename Container>
Container& split(Container& result,
				 const typename Container::value_type& s,
				 const typename Container::value_type& delimiters,
				 bool includeEmptyElements) {
	result.clear();
	size_t current;
	size_t next = -1;
	do {
		if (includeEmptyElements) {
			next = s.find_first_not_of( delimiters, next + 1 );
			if (next == Container::value_type::npos) break;
			next -= 1;
		}
		current = next + 1;
		next = s.find_first_of( delimiters, current );
		result.push_back( s.substr( current, next - current ) );
	} while (next != Container::value_type::npos);
	return result;
}

void mvk::extractTokens(string str, vector<string>& tokens) {
	split(tokens, str, " \t\n\f", false);
}

/** Compares the specified characters ignoring case. */
static bool compareIgnoringCase(unsigned char a, unsigned char b) {
	return tolower(a) == tolower(b);
}

bool mvk::equal(string const& a, string const& b, bool checkCase) {
	if (a.length() != b.length()) { return false; }
	return checkCase ? (a == b) : (equal(b.begin(), b.end(), a.begin(), compareIgnoringCase));
}

