using StellaOps.Feedser.Models;
using StellaOps.Feedser.Normalization.Cvss;

namespace StellaOps.Feedser.Normalization.Tests;

public sealed class CvssMetricNormalizerTests
{
    [Fact]
    public void TryNormalize_ComputesCvss31Defaults()
    {
        var vector = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H";

        var success = CvssMetricNormalizer.TryNormalize(null, vector, null, null, out var normalized);

        Assert.True(success);
        Assert.Equal("3.1", normalized.Version);
        Assert.Equal(vector, normalized.Vector);
        Assert.Equal(9.8, normalized.BaseScore);
        Assert.Equal("critical", normalized.BaseSeverity);

        var provenance = new AdvisoryProvenance("nvd", "cvss", "https://example", DateTimeOffset.UnixEpoch);
        var metric = normalized.ToModel(provenance);
        Assert.Equal("3.1", metric.Version);
        Assert.Equal(vector, metric.Vector);
        Assert.Equal(9.8, metric.BaseScore);
        Assert.Equal("critical", metric.BaseSeverity);
        Assert.Equal(provenance, metric.Provenance);
    }

    [Fact]
    public void TryNormalize_NormalizesCvss20Severity()
    {
        var vector = "AV:N/AC:M/Au:S/C:P/I:P/A:P";

        var success = CvssMetricNormalizer.TryNormalize("2.0", vector, 6.4, "MEDIUM", out var normalized);

        Assert.True(success);
        Assert.Equal("2.0", normalized.Version);
        Assert.Equal("CVSS:2.0/AV:N/AC:M/AU:S/C:P/I:P/A:P", normalized.Vector);
        Assert.Equal(6.0, normalized.BaseScore);
        Assert.Equal("medium", normalized.BaseSeverity);
    }

    [Fact]
    public void TryNormalize_ReturnsFalseWhenVectorMissing()
    {
        var success = CvssMetricNormalizer.TryNormalize("3.1", string.Empty, 9.8, "CRITICAL", out var normalized);

        Assert.False(success);
        Assert.Equal(default, normalized);
    }
}
