using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace ResBuilder
{
    class LuaProcessor
    {
        public readonly string inputPath;

        public readonly string outputPath;

        public readonly string tmpPath;

        public readonly string jitToolsPath;

        public LuaProcessor(string input, string output , string tmpPath , string jitExePath)
        {
            this.inputPath  = input;
            this.outputPath = output;
            this.tmpPath = tmpPath;
            this.jitToolsPath = jitExePath;
        }

        internal void Execute()
        {
            if (Program.IsJitLuaBytes)
            {
                Execute(inputPath, tmpPath);
                ExecuteLuaJitFile(jitToolsPath, tmpPath, outputPath);
            }
            else
            {
                Execute(inputPath, outputPath);
            }
        }

        static void Execute(string dir, string outputPath, SearchOption sopt = SearchOption.AllDirectories)
        {
            var fileNames = Directory.GetFiles(dir, "*.lua", sopt);
            // -- 1 Hash 文件名称
            var nameHashs = new uint[fileNames.Length];
            var fileNameHash = new Dictionary<uint, string>();
            for (int i = 0; i < fileNames.Length; i++)
            {
                var relativeFilePath = fileNames[i].Substring(dir.Length + 1);
                var hash = Tools.HashFileNameWithoutExtension(relativeFilePath);
                if (fileNameHash.ContainsKey(hash))
                {
                    throw new Exception(string.Format("文件名hash冲突:{0} -> {1}", fileNameHash[hash], relativeFilePath));
                }
                else
                {
                    fileNameHash.Add(hash, relativeFilePath);
                }
                nameHashs[i] = hash;
            }
            // -- 2 处理lua文件
            var fileBytes = new byte[fileNames.Length][];
            var logger = new StringBuilder();
            for (int i = 0; i < fileNames.Length; i++)
            {
                fileBytes[i] = GetLuaFileBytes(fileNames[i], logger);
            }
            if (logger.Length > 0)
            {
                File.WriteAllText("luaChanges.log", logger.ToString());
            }
            if (fileNames.Length > 0 && !Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }
            // -- 3 写入处理后的lua文件
            for (int i = 0; i < fileNames.Length; i++)
            {
                var outFilePath = Path.Combine(outputPath, Convert.ToString(nameHashs[i], 16) + ".lua");
                File.WriteAllBytes(outFilePath, fileBytes[i]);
            }
        }

        static byte[] GetLuaFileBytes(string filePath, StringBuilder logger)
        {
            var str = LuaFileTools.RemoveLuaFileComment(filePath, logger);
            var bytes = Tools.UTF8.GetBytes(str);
            if (Program.IsZipLuaBytes)
            {
                bytes = LZMAHelper.Compress(bytes);
            }
            return bytes;
        }

        static void ExecuteLuaJitFile(string luajitPath, string inputPath, string outPath)
        {
            inputPath = inputPath.Replace("/","\\");
            var files = Directory.GetFiles(inputPath, "*.lua", SearchOption.AllDirectories);
            foreach (var f in files)
            {
                Console.WriteLine("luajit->" + f);
                var outfile = Path.Combine(outPath, f.Substring(inputPath.Length + 1));
                var outDir = Path.GetDirectoryName(outfile);
                if (!Directory.Exists(outDir))
                {
                    Directory.CreateDirectory(outDir);
                }
                var args = string.Format("-b {0} {1}", f, outfile);
                Program.StartProcess(luajitPath, args);
            }
        }
    }
}