using Microsoft.Extensions.Logging;
using System.Text;

namespace File_Folder_Helper.ADO2024.PI1;

internal static partial class Helper20240426
{

    private static void Write(string toA, string toB, string matchA, string matchB, string file, List<string> lines)
    {
        StringBuilder stringBuilder = new();
        foreach (string line in lines)
            _ = stringBuilder.AppendLine(line.Replace(matchB, toB));
        string checkFile = file.Replace(matchA, toA);
        _ = Directory.CreateDirectory(Path.GetDirectoryName(checkFile) ?? throw new NullReferenceException());
        if (!File.Exists(checkFile))
            File.WriteAllText(checkFile, stringBuilder.ToString());
    }

    private static void UpdateTestFiles(ILogger<Worker> logger, string to, string match, string staticDirectoryName, List<string> files)
    {
        List<string> lines;
        string directoryName;
        string fistLineCheck;
        string lastLineCheck = "#endif";
        foreach (string file in files)
        {
            directoryName = Path.GetFileName(Path.GetDirectoryName(file) ?? throw new NullReferenceException(nameof(directoryName)));
            if (directoryName == staticDirectoryName)
                continue;
            lines = File.ReadAllLines(file).ToList();
            if (directoryName == match)
                Write(to, to.Replace('.', '_'), match, match.Replace('.', '_'), file, lines);
            if (lines.Count < 3)
                continue;
            fistLineCheck = $"#if {directoryName.Replace('.', '_')}";
            if (lines[0].StartsWith("#if true") || lines[0].StartsWith(fistLineCheck))
                continue;
            for (int i = lines.Count - 1; i > 0; i--)
            {
                if (!string.IsNullOrEmpty(lines[i]))
                    break;
                lines.RemoveAt(i);
            }
            if (lines[^1].StartsWith(lastLineCheck))
                continue;
            if (lines.All(l => string.IsNullOrEmpty(l) || l.StartsWith("//")))
                continue;
            lines.Add(lastLineCheck);
            lines.Insert(0, fistLineCheck);
            File.WriteAllText(file, string.Join(Environment.NewLine, lines));
            logger.LogDebug(file);
        }
    }

    private static void UpdateProjectTests(ILogger<Worker> logger, string to, string match, string searchPattern, string staticDirectoryName, string extractDirectoryName, string createSelfDescriptionDirectoryName, string sourceCodeDirectory)
    {
        List<string> files = [];
        List<string> knownDirectories = [];
        knownDirectories.AddRange(Directory.GetDirectories(sourceCodeDirectory, createSelfDescriptionDirectoryName, SearchOption.AllDirectories));
        knownDirectories.AddRange(Directory.GetDirectories(sourceCodeDirectory, extractDirectoryName, SearchOption.AllDirectories));
        knownDirectories.AddRange(Directory.GetDirectories(sourceCodeDirectory, staticDirectoryName, SearchOption.AllDirectories));
        foreach (string knownDirectory in knownDirectories)
            files.AddRange(Directory.GetFiles(knownDirectory, searchPattern, SearchOption.AllDirectories));
        logger.LogInformation("{directory} has {files} file(s)", sourceCodeDirectory, files.Count);
        UpdateTestFiles(logger, to, match, staticDirectoryName, files);
    }

    internal static void UpdateTests(ILogger<Worker> logger, List<string> args)
    {
        string to = args[9];
        string match = args[8];
        string searchPattern = args[7];
        string[] sourceCodeDirectories;
        string staticDirectoryName = args[6];
        string extractDirectoryName = args[5];
        string sourceCodeDirectoryName = args[3];
        string directory = Path.GetFullPath(args[0]);
        string createSelfDescriptionDirectoryName = args[4];
        string systemVolumeInformation = Path.Combine(directory, args[2]);
        string[] subDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
        foreach (string subDirectory in subDirectories)
        {
            if (subDirectory == systemVolumeInformation)
                continue;
            sourceCodeDirectories = Directory.GetDirectories(subDirectory, sourceCodeDirectoryName, SearchOption.AllDirectories);
            if (sourceCodeDirectories.Length != 1)
                continue;
            UpdateProjectTests(logger, to, match, searchPattern, staticDirectoryName, extractDirectoryName, createSelfDescriptionDirectoryName, sourceCodeDirectories[0]);
        }
    }

}