using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;

namespace StellaOps.Feedser.Models;

/// <summary>
/// Emits telemetry for OSV vs GHSA parity reports so QA dashboards can track regression trends.
/// </summary>
public static class OsvGhsaParityDiagnostics
{
    private static readonly Meter Meter = new("StellaOps.Feedser.Models.OsvGhsaParity");
    private static readonly Counter<long> TotalCounter = Meter.CreateCounter<long>(
        "feedser.osv_ghsa.total",
        unit: "count",
        description: "Total GHSA identifiers evaluated for OSV parity.");
    private static readonly Counter<long> IssueCounter = Meter.CreateCounter<long>(
        "feedser.osv_ghsa.issues",
        unit: "count",
        description: "Parity issues grouped by dataset, issue kind, and field mask.");

    public static void RecordReport(OsvGhsaParityReport report, string dataset)
    {
        ArgumentNullException.ThrowIfNull(report);
        dataset = NormalizeDataset(dataset);

        if (report.TotalGhsaIds > 0)
        {
            TotalCounter.Add(report.TotalGhsaIds, CreateTotalTags(dataset));
        }

        if (!report.HasIssues)
        {
            return;
        }

        foreach (var issue in report.Issues)
        {
            IssueCounter.Add(1, CreateIssueTags(dataset, issue));
        }
    }

    private static KeyValuePair<string, object?>[] CreateTotalTags(string dataset)
        => new[]
        {
            new KeyValuePair<string, object?>("dataset", dataset),
        };

    private static KeyValuePair<string, object?>[] CreateIssueTags(string dataset, OsvGhsaParityIssue issue)
    {
        var mask = issue.FieldMask.IsDefaultOrEmpty
            ? "none"
            : string.Join('|', issue.FieldMask);

        return new[]
        {
            new KeyValuePair<string, object?>("dataset", dataset),
            new KeyValuePair<string, object?>("issueKind", issue.IssueKind),
            new KeyValuePair<string, object?>("fieldMask", mask),
        };
    }

    private static string NormalizeDataset(string dataset)
    {
        if (string.IsNullOrWhiteSpace(dataset))
        {
            return "default";
        }

        return dataset.Trim().ToLowerInvariant();
    }
}
