using NodePipeline.Engine.CodeGeneration.Abstractions;
using NodePipeline.Engine.DependencyInjection.CodeGeneration;
using NodePipeline.Engine.Tests.CodeGeneratorTests.Fixtures;

namespace NodePipeline.Engine.Tests.CodeGeneratorTests;

public class DiNodeFactoryGeneratorTests
{
    [Fact]
    public void InitializeNodeFactoriesMethod_ShouldExistInGeneratedCode()
    {
        var methodSignature = "private void InitializeNodeFactories()";
        var model = TestNodeModelFactory.CreateMultipleNodesModel();

        var generatedCode = NodeFactoryGenerator.Generate(model);

        Assert.Contains(methodSignature, generatedCode);
    }

    [Fact]
    public void InitializeNodeFactoriesMethod_ContainsFactoryRegistrations()
    {
        var model = TestNodeModelFactory.CreateMultipleNodesModel();
        var methodName = "InitializeNodeFactories";

        var generatedCode = NodeFactoryGenerator.Generate(model);
        var methodCode = TestHelper.ExtractMethod(generatedCode, methodName);

        foreach (var node in model.Nodes)
        {
            if (node.HasParameterlessConstructor)
                continue;

            var nodeName = NodeGeneratorHelper.GetNodeName(node);
            var expected = "_nodeFactory.NodeFactories.Add(" + Environment.NewLine
                                                             + $"            {nodeName}," + Environment.NewLine
                                                             + $"            () => _serviceProvider.GetRequiredService<{node.TypeNameFull}>())";

            Assert.Contains(expected, methodCode);
        }
    }
}