using Microsoft.VisualBasic;
using static Microsoft.VisualBasic.CompilerServices.LikeOperator;
using System;
using System.Collections.Generic;
using System.IO;
using System.Resources;
using System.Collections;
using System.Linq;
using Microsoft.WindowsAPICodePack.Dialogs;
using Newtonsoft.Json.Linq;
using System.Reflection;

namespace SM64_ROM_Manager.LangRes_Collector
{
    class Program
    {
        static void Main(string[] args)
        {
            var resFiles = new List<string>();
            var ofd = new CommonOpenFileDialog { IsFolderPicker = true };
            string rootPath, outputPath;
            var myAppDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var myConfigFilePath = Path.Combine(myAppDir, "FilterConfig.json");
            var filterConfig = JObject.Parse(File.ReadAllText(myConfigFilePath)).ToObject<LangResFilterConfig>();

            // Get root path
            ofd.Title = "Root (repository) directory";
            if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
                rootPath = ofd.FileName;
            else
                return;

            // Get output path
            ofd.Title = "Output directory";
            if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
                outputPath = ofd.FileName;
            else
                return;

            // Collect files
            if (Directory.Exists(rootPath))
            {
                foreach (var filePath in Directory.GetFiles(rootPath, string.Empty, SearchOption.AllDirectories))
                {
                    var fileName = Path.GetFileName(filePath);
                    var copyFile = true;

                    foreach (var blackFileName in filterConfig.FileNameBlackList)
                    {
                        if (copyFile && LikeString(fileName, blackFileName, CompareMethod.Binary))
                            copyFile = false;
                    }

                    foreach (var whiteFileName in filterConfig.FileNameWhiteList)
                    {
                        if (copyFile && !LikeString(fileName, whiteFileName, CompareMethod.Binary))
                            copyFile = false;
                    }

                    if (copyFile)
                        resFiles.Add(filePath);
                }
            }

            // Create output path if not exists
            Directory.CreateDirectory(outputPath);

            // Copy and prepair files
            foreach (var resFileInput in resFiles)
            {
                var resReader = new ResXResourceReader(resFileInput);
                var propsToCopy = new Dictionary<string, string>();

                // Collect input properties
                foreach (DictionaryEntry kvp in resReader)
                {
                    var propName = (string)kvp.Key;
                    var useProp = true;

                    // Check for blacklisted property names
                    foreach (var blackPropName in filterConfig.PropNameBlackList)
                    {
                        if (useProp && LikeString(propName, blackPropName, CompareMethod.Binary))
                            useProp = false;
                    }

                    // Hold property to write later, if it's a string
                    if (useProp && kvp.Value is string val)
                    {
                        if (!string.IsNullOrEmpty(val))
                            propsToCopy.Add(propName, (string)kvp.Value);
                    }
                }

                resReader.Close();

                // Write output ResX file
                if (propsToCopy.Any())
                {
                    var resFileOutput = Path.Combine(outputPath, resFileInput.Replace(rootPath, outputPath));
                    var resFileOutputDir = Path.GetDirectoryName(resFileOutput);

                    // Ensure the directory exists
                    Directory.CreateDirectory(resFileOutputDir);

                    // Open a ResXResourceWriter
                    var resWriter = new ResXResourceWriter(resFileOutput);

                    // Write all hold properties
                    foreach (var kvp in propsToCopy)
                        resWriter.AddResource(kvp.Key, kvp.Value);

                    resWriter.Close();
                }
            }
        }
    }
}
