using System;
using StellaOps.Feedser.Models;
using Xunit;

namespace StellaOps.Feedser.Models.Tests;

public sealed class AffectedVersionRangeExtensionsTests
{
    [Fact]
    public void ToNormalizedVersionRule_UsesNevraPrimitivesWhenAvailable()
    {
        var range = new AffectedVersionRange(
            rangeKind: "nevra",
            introducedVersion: "raw-introduced",
            fixedVersion: "raw-fixed",
            lastAffectedVersion: null,
            rangeExpression: null,
            provenance: AdvisoryProvenance.Empty,
            primitives: new RangePrimitives(
                SemVer: null,
                Nevra: new NevraPrimitive(
                    new NevraComponent("pkg", 0, "1.0.0", "1", "x86_64"),
                    new NevraComponent("pkg", 0, "1.2.0", "2", "x86_64"),
                    null),
                Evr: null,
                VendorExtensions: null));

        var rule = range.ToNormalizedVersionRule();

        Assert.NotNull(rule);
        Assert.Equal(NormalizedVersionSchemes.Nevra, rule!.Scheme);
        Assert.Equal("pkg-1.0.0-1.x86_64", rule.Min);
        Assert.Equal("pkg-1.2.0-2.x86_64", rule.Max);
    }

    [Fact]
    public void ToNormalizedVersionRule_FallsBackForEvrWhenPrimitivesMissing()
    {
        var range = new AffectedVersionRange(
            rangeKind: "EVR",
            introducedVersion: "1:1.0.0-1",
            fixedVersion: "1:1.2.0-1ubuntu2",
            lastAffectedVersion: null,
            rangeExpression: null,
            provenance: new AdvisoryProvenance("debian", "range", "pkg", DateTimeOffset.UtcNow),
            primitives: null);

        var rule = range.ToNormalizedVersionRule("fallback");

        Assert.NotNull(rule);
        Assert.Equal(NormalizedVersionSchemes.Evr, rule!.Scheme);
        Assert.Equal(NormalizedVersionRuleTypes.Range, rule.Type);
        Assert.Equal("1:1.0.0-1", rule.Min);
        Assert.Equal("1:1.2.0-1ubuntu2", rule.Max);
        Assert.Equal("fallback", rule.Notes);
    }

    [Fact]
    public void ToNormalizedVersionRule_ReturnsNullForUnknownKind()
    {
        var range = new AffectedVersionRange(
            rangeKind: "vendor",
            introducedVersion: null,
            fixedVersion: null,
            lastAffectedVersion: null,
            rangeExpression: null,
            provenance: AdvisoryProvenance.Empty,
            primitives: null);

        var rule = range.ToNormalizedVersionRule();

        Assert.Null(rule);
    }
}
