using System;
using System.Collections.Generic;

namespace NodePipeline.Engine.CodeGeneration.Abstractions.Models;

public sealed class NodeDescriptor
{
    private readonly HashSet<ValidatorDescriptor> _customValidators = [];
    private string _typeNameShortSanitized = string.Empty;

    public NodeDescriptor(string type, bool isNameDefinedInAttribute, string typeNameShort, string typeNameFull,
        IReadOnlyList<NodeFieldDescriptor> fields, bool hasParameterlessConstructor,
        ICollection<ValidatorDescriptor>? customValidators)
    {
        Type = type ?? throw new ArgumentNullException(nameof(type));
        IsNameDefinedInAttribute = isNameDefinedInAttribute;
        TypeNameShort = typeNameShort ?? throw new ArgumentNullException(nameof(typeNameShort));

        TypeNameFull = typeNameFull ?? throw new ArgumentNullException(nameof(typeNameFull));
        Fields = fields ?? throw new ArgumentNullException(nameof(fields));
        HasParameterlessConstructor = hasParameterlessConstructor;
        if (customValidators == null) return;
        foreach (var validatorType in customValidators) _customValidators.Add(validatorType);
    }

    /// <summary>
    ///     Node type (not C# type)
    /// </summary>
    public string Type { get; }

    /// <summary>
    ///     C# node type except "global" prefix and user specified prefix
    /// </summary>
    public string TypeNameShort { get; }

    public string TypeNameShortSanitized
    {
        get
        {
            if (string.IsNullOrWhiteSpace(_typeNameShortSanitized))
                _typeNameShortSanitized = TypeNameShort.Replace('.', '_');
            return _typeNameShortSanitized;
        }
    }

    /// <summary>
    ///     Node C# type
    /// </summary>
    public string TypeNameFull { get; }

    public bool HasParameterlessConstructor { get; }
    public IReadOnlyList<NodeFieldDescriptor> Fields { get; }
    public IReadOnlyCollection<ValidatorDescriptor> CustomValidators => _customValidators;
    public bool IsNameDefinedInAttribute { get; }
}