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

namespace NodePipeline.Engine.Tests.CodeGeneratorTests;

public class DiNodeValidatorGeneratorTests
{
    [Fact]
    public void InitializeNodeValidatorsMethod_ShouldExistInGeneratedCode()
    {
        var methodSignature = "private void InitializeNodeValidators()";
        var model = TestNodeModelFactory.CreateMultipleNodesModel();

        var generatedCode = NodeValidatorGenerator.Generate(model);

        Assert.Contains(methodSignature, generatedCode);
    }

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

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

        var validators = model.Nodes.SelectMany(n => n.CustomValidators);

        foreach (var validator in validators)
        {
            if (validator.CanBeInitialized)
                continue;

            var expected = $"_validator.NodeValidators.TryAdd(typeof({validator}),";
            Assert.Contains(expected, methodCode);

            var expectedService = $"_serviceProvider.GetRequiredService<{validator}>()";
            Assert.Contains(expectedService, methodCode);
        }
    }
}