using System.Diagnostics.Metrics;

namespace StellaOps.Feedser.Source.Nvd.Internal;

public sealed class NvdDiagnostics : IDisposable
{
    public const string MeterName = "StellaOps.Feedser.Source.Nvd";
    public const string MeterVersion = "1.0.0";

    private readonly Meter _meter;
    private readonly Counter<long> _fetchAttempts;
    private readonly Counter<long> _fetchDocuments;
    private readonly Counter<long> _fetchFailures;
    private readonly Counter<long> _fetchUnchanged;
    private readonly Counter<long> _parseSuccess;
    private readonly Counter<long> _parseFailures;
    private readonly Counter<long> _parseQuarantine;
    private readonly Counter<long> _mapSuccess;

    public NvdDiagnostics()
    {
        _meter = new Meter(MeterName, MeterVersion);
        _fetchAttempts = _meter.CreateCounter<long>(
            name: "nvd.fetch.attempts",
            unit: "operations",
            description: "Number of NVD fetch operations attempted, including paginated windows.");
        _fetchDocuments = _meter.CreateCounter<long>(
            name: "nvd.fetch.documents",
            unit: "documents",
            description: "Count of NVD documents fetched and persisted.");
        _fetchFailures = _meter.CreateCounter<long>(
            name: "nvd.fetch.failures",
            unit: "operations",
            description: "Count of NVD fetch attempts that resulted in an error or missing document.");
        _fetchUnchanged = _meter.CreateCounter<long>(
            name: "nvd.fetch.unchanged",
            unit: "operations",
            description: "Count of NVD fetch attempts returning 304 Not Modified.");
        _parseSuccess = _meter.CreateCounter<long>(
            name: "nvd.parse.success",
            unit: "documents",
            description: "Count of NVD documents successfully validated and converted into DTOs.");
        _parseFailures = _meter.CreateCounter<long>(
            name: "nvd.parse.failures",
            unit: "documents",
            description: "Count of NVD documents that failed parsing due to missing content or read errors.");
        _parseQuarantine = _meter.CreateCounter<long>(
            name: "nvd.parse.quarantine",
            unit: "documents",
            description: "Count of NVD documents quarantined due to schema validation failures.");
        _mapSuccess = _meter.CreateCounter<long>(
            name: "nvd.map.success",
            unit: "advisories",
            description: "Count of canonical advisories produced by NVD mapping.");
    }

    public void FetchAttempt() => _fetchAttempts.Add(1);

    public void FetchDocument() => _fetchDocuments.Add(1);

    public void FetchFailure() => _fetchFailures.Add(1);

    public void FetchUnchanged() => _fetchUnchanged.Add(1);

    public void ParseSuccess() => _parseSuccess.Add(1);

    public void ParseFailure() => _parseFailures.Add(1);

    public void ParseQuarantine() => _parseQuarantine.Add(1);

    public void MapSuccess(long count = 1) => _mapSuccess.Add(count);

    public Meter Meter => _meter;

    public void Dispose() => _meter.Dispose();
}
