﻿using CircuitDiagram.CLI.ComponentPreview;
using CircuitDiagram.Compiler;
using CircuitDiagram.TypeDescription;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace CircuitDiagram.CLI.Component.OutputGenerators
{
    public class OutputRunner
    {
        private readonly ILogger logger;
        private readonly IResourceProvider resourceProvider;

        public OutputRunner(ILogger<OutputRunner> logger, IResourceProvider resourceProvider)
        {
            this.logger = logger;
            this.resourceProvider = resourceProvider;
        }

        public IEnumerable<KeyValuePair<string, string>> Generate(FileStream input,
                                                                  ComponentDescription description,
                                                                  ComponentConfiguration configuration,
                                                                  string inputBaseName,
                                                                  IDictionary<IOutputGenerator, string> formats,
                                                                  PreviewGenerationOptions previewOptions,
                                                                  SourceFileType sourceType)
        {
            foreach (var f in formats)
            {
                if (!f.Key.AcceptsSourceFileType(sourceType))
                    continue;

                string format = f.Key.Format;

                if (sourceType == SourceFileType.ComponentDescriptionConfiguration)
                    inputBaseName += $"--{Regex.Replace(configuration.Name.ToLowerInvariant().Replace(" ", "_"), "[^a-z0-9_]", "")}";

                string autoGeneratedName = $"{inputBaseName}{f.Key.FileExtension}";
                string outputPath = f.Value != null && Directory.Exists(f.Value) ? Path.Combine(f.Value, autoGeneratedName) : f.Value ?? autoGeneratedName;
                using (var output = File.Open(outputPath, FileMode.Create))
                {
                    logger.LogDebug($"Starting {format} generation.");
                    input.Seek(0, SeekOrigin.Begin);
                    f.Key.Generate(description,
                                   configuration,
                                   resourceProvider,
                                   previewOptions,
                                   input,
                                   output,
                                   sourceType);
                    logger.LogInformation($"  {format,-4} -> {outputPath}");
                }

                yield return new KeyValuePair<string, string>(format, outputPath);
            }
        }
    }
}
