namespace StellaOps.Feedser.Models;

/// <summary>
/// Helper extensions for converting <see cref="EvrPrimitive"/> instances into normalized rules.
/// </summary>
public static class EvrPrimitiveExtensions
{
    public static NormalizedVersionRule? ToNormalizedVersionRule(this EvrPrimitive? primitive, string? notes = null)
    {
        if (primitive is null)
        {
            return null;
        }

        var resolvedNotes = Validation.TrimToNull(notes);
        var introduced = Normalize(primitive.Introduced);
        var fixedVersion = Normalize(primitive.Fixed);
        var lastAffected = Normalize(primitive.LastAffected);
        var scheme = NormalizedVersionSchemes.Evr;

        if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(fixedVersion))
        {
            return new NormalizedVersionRule(
                scheme,
                NormalizedVersionRuleTypes.Range,
                min: introduced,
                minInclusive: true,
                max: fixedVersion,
                maxInclusive: false,
                notes: resolvedNotes);
        }

        if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(lastAffected))
        {
            return new NormalizedVersionRule(
                scheme,
                NormalizedVersionRuleTypes.Range,
                min: introduced,
                minInclusive: true,
                max: lastAffected,
                maxInclusive: true,
                notes: resolvedNotes);
        }

        if (!string.IsNullOrEmpty(introduced))
        {
            return new NormalizedVersionRule(
                scheme,
                NormalizedVersionRuleTypes.GreaterThanOrEqual,
                min: introduced,
                minInclusive: true,
                notes: resolvedNotes);
        }

        if (!string.IsNullOrEmpty(fixedVersion))
        {
            return new NormalizedVersionRule(
                scheme,
                NormalizedVersionRuleTypes.LessThan,
                max: fixedVersion,
                maxInclusive: false,
                notes: resolvedNotes);
        }

        if (!string.IsNullOrEmpty(lastAffected))
        {
            return new NormalizedVersionRule(
                scheme,
                NormalizedVersionRuleTypes.LessThanOrEqual,
                max: lastAffected,
                maxInclusive: true,
                notes: resolvedNotes);
        }

        return null;
    }

    private static string? Normalize(EvrComponent? component)
    {
        if (component is null)
        {
            return null;
        }

        return Validation.TrimToNull(component.ToCanonicalString());
    }
}
