using System;
using System.Collections.Generic;

namespace StellaOps.Feedser.Models;

/// <summary>
/// Optional structured representations of range semantics attached to <see cref="AffectedVersionRange"/>.
/// </summary>
public sealed record RangePrimitives(
    SemVerPrimitive? SemVer,
    NevraPrimitive? Nevra,
    EvrPrimitive? Evr,
    IReadOnlyDictionary<string, string>? VendorExtensions)
{
    public bool HasVendorExtensions => VendorExtensions is { Count: > 0 };

    public string GetCoverageTag()
    {
        var kinds = new List<string>(3);
        if (SemVer is not null)
        {
            kinds.Add("semver");
        }

        if (Nevra is not null)
        {
            kinds.Add("nevra");
        }

        if (Evr is not null)
        {
            kinds.Add("evr");
        }

        if (kinds.Count == 0)
        {
            return HasVendorExtensions ? "vendor" : "none";
        }

        kinds.Sort(StringComparer.Ordinal);
        return string.Join('+', kinds);
    }
}

/// <summary>
/// Structured SemVer metadata for a version range.
/// </summary>
public sealed record SemVerPrimitive(
    string? Introduced,
    bool IntroducedInclusive,
    string? Fixed,
    bool FixedInclusive,
    string? LastAffected,
    bool LastAffectedInclusive,
    string? ConstraintExpression);

/// <summary>
/// Structured NEVRA metadata for a version range.
/// </summary>
public sealed record NevraPrimitive(
    NevraComponent? Introduced,
    NevraComponent? Fixed,
    NevraComponent? LastAffected);

/// <summary>
/// Structured Debian EVR metadata for a version range.
/// </summary>
public sealed record EvrPrimitive(
    EvrComponent? Introduced,
    EvrComponent? Fixed,
    EvrComponent? LastAffected);

/// <summary>
/// Normalized NEVRA component.
/// </summary>
public sealed record NevraComponent(
    string Name,
    int Epoch,
    string Version,
    string Release,
    string? Architecture);

/// <summary>
/// Normalized EVR component (epoch:upstream revision).
/// </summary>
public sealed record EvrComponent(
    int Epoch,
    string UpstreamVersion,
    string? Revision);
