using Common.Extensions;
using Ocr.Report.Models;
using ReportGeneration.Generators;
using ReportGeneration.Generators.LatexInclude;

namespace Ocr.Report;

internal static class Program
{
  internal static void Main(string[] args)
  {
    // Retrieve data

    Console.WriteLine("Getting data");
    var tagFileInfos = GetTagFileInfos(args[0]);
    var scanFileInfos = GetScanFileInfos(args[1]);

    // Parse

    Console.WriteLine("Generating report");
    var scans = Scan(tagFileInfos, scanFileInfos);

    var path = Path.GetFullPath("report");

    using var document = new LatexIncludeDocumentGenerator(path, true);
    using var report = new ReportGenerator("OCR Report", document, scans)
      .AddComparison("Processing summary (Average)", v =>
      {
        var result = v.Average(out var deviation);
        return (result, deviation);
      })
      .AddComparison("Processing summary (Median)", v =>
      {
        var result = v.Median(out var deviation);
        return (result, deviation);
      })
      .AddProcessorStats("Processor Stats")
      .AddImageStatsFull("Scan Results");

    Console.WriteLine($"Saved report to '{path}'");
  }

  private static IEnumerable<ImageStats> Scan(
    IEnumerable<TagFileInfo> tagFileInfos,
    IEnumerable<ScanFileInfo> scanFileInfos
  )
  {
    var scanFileLookup = scanFileInfos.ToLookup(i => i.ImageName);
    foreach (var i in tagFileInfos)
    {
      yield return new ImageStats(
        i.ImageName,
        i.GetWords().Distinct().OrderBy(w => w).ToArray(),
        scanFileLookup[i.ImageName]
      );
    }
  }

  private static IEnumerable<TagFileInfo> GetTagFileInfos(string dir)
  {
    if (!Directory.Exists(dir))
    {
      throw new ArgumentException($"Invalid tagged data directory '{dir}'");
    }

    return Directory.EnumerateFiles(dir, "*.json").Select(TagFileInfo.FromPath);
  }

  private static IEnumerable<ScanFileInfo> GetScanFileInfos(string dir)
  {
    if (!Directory.Exists(dir))
    {
      throw new ArgumentException($"Invalid scan results directory '{dir}'");
    }

    return Directory.EnumerateFiles(dir, "*.json").Select(ScanFileInfo.FromPath);
  }
}
