using Compare.Client;
using Compare.Helpers;
using Compare.Models;
using System.Diagnostics;

static class Program
{
    public static readonly Config Config = Config.Load();
    public static List<FhirSession> Sessions = new();

    static async Task<int> Main(string[] args)
    {
        if (Debugger.IsAttached)
        {
            args = new string[] { "--compare" };
        }        

        var command = args.FirstOrDefault()?.ToLower() ?? null;
        return command switch
        {
            "--import" => await ImportTestdata(args.Skip(1).ToArray()),
            "--compare" => await ShowComparisation(args.Skip(1).ToArray()),
            _ => ShowHelp()
        };
    }

    static int ShowHelp()
    {
        Console.WriteLine("Usage: compare.exe \e[33m--import\e[0m");
        Console.WriteLine("Usage: compare.exe \e[33m--import\e[0m hapi");
        Console.WriteLine("Usage: compare.exe \e[33m--compare\e[0m");
        return -1;
    }

    static async Task<int> ImportTestdata(string[] args)
    {
        var stopwatch = Stopwatch.StartNew();
        var testdataDefinitions = Directory.GetFiles(Path.Combine(Program.Config.RootDir, Program.Config.ImportRelativePath, "resources"), "*.xml", SearchOption.AllDirectories);
        var testdataExamples = Directory.GetFiles(Path.Combine(Program.Config.RootDir, Program.Config.ImportRelativePath, "examples"), "*.xml", SearchOption.AllDirectories);

        foreach (var server in Program.Config.ServersEnabled)
        {
            var session = await FhirSession.CreateSession(server);
            if (session.IsAvailable)
            {
                Console.WriteLine();
                Console.WriteLine($"Importeren testdata op {server.Name}:");
                Console.WriteLine();

                int countResources = 0;
                Console.WriteLine($"Importeren van {testdataDefinitions.Length} definities voor profielen, codelijsten enz.");
                Console.WriteLine();
                foreach (var file in testdataDefinitions)
                {
                    Console.WriteLine($" - [{++countResources}/{testdataDefinitions.Length}] Definitie: {Path.GetFileName(file)}");
                    await session.Import(session, file);
                }

                int countExamples = 0;
                Console.WriteLine($"Importeren van {testdataExamples.Length} voorbeelden.");
                Console.WriteLine();
                foreach (var file in testdataExamples)
                {
                    Console.WriteLine($" - [{++countExamples}/{testdataExamples.Length}] Voorbeeld: {Path.GetFileName(file)}");
                    await session.Import(session, file);
                }
            }
        }

        stopwatch.Stop();
        var elapsed = stopwatch.Elapsed;
        Console.WriteLine($"{elapsed.Minutes:D2}:{elapsed.Seconds:D2}");

        return 0;
    }

    static async Task<int> ShowComparisation(string[] args)
    {
        // Capabilities table.
        foreach (var server in Program.Config.Servers)
        {
            Sessions.Add(await FhirSession.CreateSession(server));
            Console.WriteLine($" - Session met {server.Name}");
        }
        Console.WriteLine();
        Console.WriteLine(Sessions.FormatCapabilities());

        // Operation $everything
        var tests = new FhirTest(Sessions);
        await tests.RunAsync(FhirQuery.Test1_PatientEverything);
        await tests.RunAsync(FhirQuery.Test2_PatientEverythingWithPagination);
        await tests.RunAsync(FhirQuery.Test3_PatientIdEverything);
        await tests.RunAsync(FhirQuery.Test4_PatientIdEverythingWithPagination);

        //// Operation $export
        await tests.RunAsync(FhirQuery.Test5_PatientExport);
        await tests.RunAsync(FhirQuery.Test6_PatientIdExport);

        //// Operation $document
        await tests.RunAsync(FhirQuery.Test7_PatientDocument);
        await tests.RunAsync(FhirQuery.Test8_PatientIdDocument);
        await tests.RunAsync(FhirQuery.Test9_PatientIdEverythingWithInclude);
        await tests.RunAsync(FhirQuery.Test10_PatientIdEverythingWithIncludes);
        await tests.RunAsync(FhirQuery.Test11_PatientIdEverythingWithIncludeWildcard);
        await tests.RunAsync(FhirQuery.Test12_PatientIdEverythingWithType);
        Console.WriteLine(Sessions.FormatOperations());

        return 0;
    }

    
}
