using System.Linq; using System.Text; using NodePipeline.Engine.CodeGeneration.Abstractions; namespace NodePipeline.Engine.DependencyInjection.CodeGeneration; internal static class NodeValidatorGenerator { public static string Generate(NodeModelBuilder.NodesModel model) { var sb = new StringBuilder(); sb.AppendLine("using Microsoft.Extensions.DependencyInjection;"); sb.AppendLine("using System.Globalization;"); sb.AppendLine("using NodePipeline.Abstractions;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces.Validation;"); sb.AppendLine("using NodePipeline.Abstractions.Models.Validation;"); sb.AppendLine("using NodePipeline.Configuration.Abstractions.Models.Execute;"); sb.AppendLine("using NodePipeline.Engine.Abstractions;"); sb.AppendLine(); sb.AppendLine("// ReSharper disable CheckNamespace"); sb.AppendLine("// ReSharper disable NotAccessedField.Local"); sb.AppendLine("#nullable enable"); sb.AppendLine(); sb.AppendLine("namespace NodePipeline.Engine.Generated;"); sb.AppendLine(); sb.AppendLine("public class DiNodeValidator : IPipelineNodeValidator"); sb.AppendLine("{"); sb.AppendLine(" private readonly IServiceProvider _serviceProvider;"); sb.AppendLine(" private readonly IPipelineNodeValidator _validator;"); sb.AppendLine(); sb.AppendLine( " public IPipelineLocalizationProvider PipelineLocalizationProvider { get; set; } = new PipelineLocalizationProvider();"); sb.AppendLine(" public Dictionary NodeValidators { get; set; } = [];"); sb.AppendLine(" public Dictionary NodeFieldValidators { get; set; } = [];"); sb.AppendLine(); sb.AppendLine( " public DiNodeValidator(IServiceProvider serviceProvider, IPipelineNodeValidator inner, IPipelineLocalizationProvider? validationLocalizationProvider = null)"); sb.AppendLine(" {"); sb.AppendLine(" _serviceProvider = serviceProvider;"); sb.AppendLine(" _validator = inner;"); sb.AppendLine(" if (validationLocalizationProvider != null)"); sb.AppendLine(" {"); sb.AppendLine(" PipelineLocalizationProvider = validationLocalizationProvider;"); sb.AppendLine(" _validator.PipelineLocalizationProvider = PipelineLocalizationProvider;"); sb.AppendLine(" }"); sb.AppendLine(" InitializeNodeValidators();"); sb.AppendLine(" InitializeNodeFieldValidators();"); sb.AppendLine(" }"); sb.AppendLine(); sb.AppendLine(BuildInitializeNodeValidatorsMethod(model)); sb.AppendLine(); sb.AppendLine(BuildInitializeNodeFieldValidatorsMethod(model)); sb.AppendLine(); sb.AppendLine(BuildValidateNodeMethod()); sb.AppendLine("}"); sb.AppendLine("#nullable restore"); return sb.ToString(); } private static string BuildInitializeNodeValidatorsMethod(NodeModelBuilder.NodesModel model) { var sb = new StringBuilder(); sb.AppendLine(" private void InitializeNodeValidators()"); sb.AppendLine(" {"); var nodeValidators = model.Nodes.SelectMany(q => q.CustomValidators); foreach (var validator in nodeValidators) { if (validator.CanBeInitialized) continue; sb.AppendLine($" _validator.NodeValidators.TryAdd(typeof({validator.ValidatorType}),"); sb.AppendLine($" _serviceProvider.GetRequiredService<{validator.ValidatorType}>());"); } sb.AppendLine(" }"); return sb.ToString(); } private static string BuildInitializeNodeFieldValidatorsMethod(NodeModelBuilder.NodesModel model) { var sb = new StringBuilder(); sb.AppendLine(" private void InitializeNodeFieldValidators()"); sb.AppendLine(" {"); var nodeFieldValidators = model.Nodes.SelectMany(q => q.Fields.Where(x => x.Metadata != null) .Select(x => x.Metadata!.CustomValidators)) .SelectMany(q => q); foreach (var validator in nodeFieldValidators) { if (validator.CanBeInitialized) continue; sb.AppendLine($" _validator.NodeFieldValidators.TryAdd(typeof({validator.ValidatorType}),"); sb.AppendLine($" _serviceProvider.GetRequiredService<{validator.ValidatorType}>());"); } sb.AppendLine(" }"); return sb.ToString(); } private static string BuildValidateNodeMethod() { var sb = new StringBuilder(); sb.AppendLine( " public NodeValidationResult ValidateNode(string pipelineId, INodeFactory nodeFactory, NodeConfig nodeConfig, List allNodes, Dictionary parameters, CultureInfo cultureInfo)"); sb.AppendLine(" {"); sb.AppendLine( " return _validator.ValidateNode(pipelineId, nodeFactory, nodeConfig, allNodes, parameters, cultureInfo);"); sb.AppendLine(" }"); return sb.ToString(); } }