using OTSSignsOrchestrator.Server.Jobs;

namespace OTSSignsOrchestrator.Server.Tests;

public class ByoiCertExpiryThresholdTests
{
    // ── ShouldAlert ─────────────────────────────────────────────────────────

    [Theory]
    [InlineData(61, false)]   // 61 days: above all thresholds → no alert
    [InlineData(60, true)]    // 60 days: at first threshold → alert
    [InlineData(59, true)]    // 59 days: below 60 → alert
    [InlineData(31, true)]    // 31 days: between 60 and 30 → alert
    [InlineData(30, true)]    // 30 days: at second threshold → alert
    [InlineData(8, true)]     // 8 days: between 30 and 7 → alert
    [InlineData(7, true)]     // 7 days: at critical threshold → alert
    [InlineData(1, true)]     // 1 day: below critical → alert
    [InlineData(0, true)]     // 0 days: expiry day → alert
    [InlineData(-1, true)]    // -1 day: already expired → alert
    public void ShouldAlert_ReturnsCorrectValue(double daysRemaining, bool expected)
    {
        Assert.Equal(expected, ByoiCertExpiryJob.ShouldAlert(daysRemaining));
    }

    [Fact]
    public void ShouldAlert_LargeValue_NoAlert()
    {
        Assert.False(ByoiCertExpiryJob.ShouldAlert(365));
    }

    // ── GetSeverity ─────────────────────────────────────────────────────────

    [Theory]
    [InlineData(60, "Warning")]
    [InlineData(30, "Warning")]
    [InlineData(8, "Warning")]
    [InlineData(7.01, "Warning")]
    [InlineData(7, "Critical")]    // Exactly at critical boundary
    [InlineData(6, "Critical")]
    [InlineData(1, "Critical")]
    [InlineData(0, "Critical")]
    [InlineData(-1, "Critical")]   // Already expired
    public void GetSeverity_ReturnsCorrectLevel(double daysRemaining, string expected)
    {
        Assert.Equal(expected, ByoiCertExpiryJob.GetSeverity(daysRemaining));
    }

    // ── Threshold constants ─────────────────────────────────────────────────

    [Fact]
    public void AlertThresholds_AreDescending()
    {
        var thresholds = ByoiCertExpiryJob.AlertThresholdDays;
        for (int i = 1; i < thresholds.Length; i++)
        {
            Assert.True(thresholds[i - 1] > thresholds[i],
                $"Thresholds must be in descending order: {thresholds[i - 1]} should be > {thresholds[i]}");
        }
    }

    [Fact]
    public void CriticalThreshold_IsSmallestAlertThreshold()
    {
        Assert.Equal(
            ByoiCertExpiryJob.CriticalThresholdDays,
            ByoiCertExpiryJob.AlertThresholdDays[^1]);
    }

    // ── Boundary precision ──────────────────────────────────────────────────

    [Fact]
    public void ShouldAlert_JustAboveThreshold_NoAlert()
    {
        // 60.001 days — just above 60-day threshold
        Assert.False(ByoiCertExpiryJob.ShouldAlert(60.001));
    }

    [Fact]
    public void ShouldAlert_JustBelowThreshold_Alerts()
    {
        // 59.999 days — just below 60-day threshold
        Assert.True(ByoiCertExpiryJob.ShouldAlert(59.999));
    }

    [Fact]
    public void GetSeverity_JustAboveCritical_IsWarning()
    {
        Assert.Equal("Warning", ByoiCertExpiryJob.GetSeverity(7.001));
    }

    [Fact]
    public void GetSeverity_ExactlyCritical_IsCritical()
    {
        Assert.Equal("Critical", ByoiCertExpiryJob.GetSeverity(7.0));
    }
}
