using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using NodePipeline.Engine.CodeGeneration.Abstractions;

namespace NodePipeline.Engine.DependencyInjection.CodeGeneration;

[Generator]
public class DiNodeProviderGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        var nodeSymbols = NodeGeneratorHelper.GetNodeSymbols(context);

        context.RegisterSourceOutput(nodeSymbols, (spc, symbols) =>
        {
            var nodes = symbols.Where(s => s is not null)
                .ToImmutableArray();
            var (model, diagnostics) = NodeModelBuilder.Build(nodes);

            diagnostics.ForEach(spc.ReportDiagnostic);
            if (diagnostics.Any(q => q.Severity > DiagnosticSeverity.Warning)) return;

            var diExtensionsSource = DiExtensionsGenerator.Generate(model);
            spc.AddSource("PipelineServiceCollectionExtensions.g.cs", diExtensionsSource);

            var factorySource = NodeFactoryGenerator.Generate(model);
            spc.AddSource("DiNodeFactory.g.cs", factorySource);

            var validatorSource = NodeValidatorGenerator.Generate(model);
            spc.AddSource("DiNodeValidator.g.cs", validatorSource);
        });
    }
}