using System;
using System.Collections.Immutable;

namespace StellaOps.Policy;

public enum PolicyVerdictStatus
{
    Pass,
    Blocked,
    Ignored,
    Warned,
    Deferred,
    Escalated,
    RequiresVex,
}

public sealed record PolicyVerdict(
    string FindingId,
    PolicyVerdictStatus Status,
    string? RuleName = null,
    string? RuleAction = null,
    string? Notes = null,
    double Score = 0,
    string ConfigVersion = "1.0",
    ImmutableDictionary<string, double>? Inputs = null,
    string? QuietedBy = null,
    bool Quiet = false)
{
    public static PolicyVerdict CreateBaseline(string findingId, PolicyScoringConfig scoringConfig)
    {
        var inputs = ImmutableDictionary<string, double>.Empty;
        return new PolicyVerdict(
            findingId,
            PolicyVerdictStatus.Pass,
            RuleName: null,
            RuleAction: null,
            Notes: null,
            Score: 0,
            ConfigVersion: scoringConfig.Version,
            Inputs: inputs,
            QuietedBy: null,
            Quiet: false);
    }

    public ImmutableDictionary<string, double> GetInputs()
        => Inputs ?? ImmutableDictionary<string, double>.Empty;
}

public sealed record PolicyVerdictDiff(
    PolicyVerdict Baseline,
    PolicyVerdict Projected)
{
    public bool Changed
    {
        get
        {
            if (Baseline.Status != Projected.Status)
            {
                return true;
            }

            if (!string.Equals(Baseline.RuleName, Projected.RuleName, StringComparison.Ordinal))
            {
                return true;
            }

            if (Math.Abs(Baseline.Score - Projected.Score) > 0.0001)
            {
                return true;
            }

            if (!string.Equals(Baseline.QuietedBy, Projected.QuietedBy, StringComparison.Ordinal))
            {
                return true;
            }

            return false;
        }
    }
}
