using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace StellaOps.Feedser.Source.Distro.RedHat.Internal.Models;

internal sealed class RedHatCsafEnvelope
{
    [JsonPropertyName("document")]
    public RedHatDocumentSection? Document { get; init; }

    [JsonPropertyName("product_tree")]
    public RedHatProductTree? ProductTree { get; init; }

    [JsonPropertyName("vulnerabilities")]
    public IReadOnlyList<RedHatVulnerability>? Vulnerabilities { get; init; }
}

internal sealed class RedHatDocumentSection
{
    [JsonPropertyName("aggregate_severity")]
    public RedHatAggregateSeverity? AggregateSeverity { get; init; }

    [JsonPropertyName("lang")]
    public string? Lang { get; init; }

    [JsonPropertyName("notes")]
    public IReadOnlyList<RedHatDocumentNote>? Notes { get; init; }

    [JsonPropertyName("references")]
    public IReadOnlyList<RedHatReference>? References { get; init; }

    [JsonPropertyName("title")]
    public string? Title { get; init; }

    [JsonPropertyName("tracking")]
    public RedHatTracking? Tracking { get; init; }
}

internal sealed class RedHatAggregateSeverity
{
    [JsonPropertyName("text")]
    public string? Text { get; init; }
}

internal sealed class RedHatDocumentNote
{
    [JsonPropertyName("category")]
    public string? Category { get; init; }

    [JsonPropertyName("text")]
    public string? Text { get; init; }

    public bool CategoryEquals(string value)
        => !string.IsNullOrWhiteSpace(Category)
            && string.Equals(Category, value, StringComparison.OrdinalIgnoreCase);
}

internal sealed class RedHatTracking
{
    [JsonPropertyName("id")]
    public string? Id { get; init; }

    [JsonPropertyName("initial_release_date")]
    public DateTimeOffset? InitialReleaseDate { get; init; }

    [JsonPropertyName("current_release_date")]
    public DateTimeOffset? CurrentReleaseDate { get; init; }
}

internal sealed class RedHatReference
{
    [JsonPropertyName("category")]
    public string? Category { get; init; }

    [JsonPropertyName("summary")]
    public string? Summary { get; init; }

    [JsonPropertyName("url")]
    public string? Url { get; init; }
}

internal sealed class RedHatProductTree
{
    [JsonPropertyName("branches")]
    public IReadOnlyList<RedHatProductBranch>? Branches { get; init; }
}

internal sealed class RedHatProductBranch
{
    [JsonPropertyName("category")]
    public string? Category { get; init; }

    [JsonPropertyName("name")]
    public string? Name { get; init; }

    [JsonPropertyName("product")]
    public RedHatProductNodeInfo? Product { get; init; }

    [JsonPropertyName("branches")]
    public IReadOnlyList<RedHatProductBranch>? Branches { get; init; }
}

internal sealed class RedHatProductNodeInfo
{
    [JsonPropertyName("name")]
    public string? Name { get; init; }

    [JsonPropertyName("product_id")]
    public string? ProductId { get; init; }

    [JsonPropertyName("product_identification_helper")]
    public RedHatProductIdentificationHelper? ProductIdentificationHelper { get; init; }
}

internal sealed class RedHatProductIdentificationHelper
{
    [JsonPropertyName("cpe")]
    public string? Cpe { get; init; }

    [JsonPropertyName("purl")]
    public string? Purl { get; init; }
}

internal sealed class RedHatVulnerability
{
    [JsonPropertyName("cve")]
    public string? Cve { get; init; }

    [JsonPropertyName("references")]
    public IReadOnlyList<RedHatReference>? References { get; init; }

    [JsonPropertyName("scores")]
    public IReadOnlyList<RedHatVulnerabilityScore>? Scores { get; init; }

    [JsonPropertyName("product_status")]
    public RedHatProductStatus? ProductStatus { get; init; }
}

internal sealed class RedHatVulnerabilityScore
{
    [JsonPropertyName("cvss_v3")]
    public RedHatCvssV3? CvssV3 { get; init; }
}

internal sealed class RedHatCvssV3
{
    [JsonPropertyName("baseScore")]
    public double? BaseScore { get; init; }

    [JsonPropertyName("baseSeverity")]
    public string? BaseSeverity { get; init; }

    [JsonPropertyName("vectorString")]
    public string? VectorString { get; init; }

    [JsonPropertyName("version")]
    public string? Version { get; init; }
}

internal sealed class RedHatProductStatus
{
    [JsonPropertyName("fixed")]
    public IReadOnlyList<string>? Fixed { get; init; }

    [JsonPropertyName("first_fixed")]
    public IReadOnlyList<string>? FirstFixed { get; init; }

    [JsonPropertyName("known_affected")]
    public IReadOnlyList<string>? KnownAffected { get; init; }

    [JsonPropertyName("known_not_affected")]
    public IReadOnlyList<string>? KnownNotAffected { get; init; }

    [JsonPropertyName("under_investigation")]
    public IReadOnlyList<string>? UnderInvestigation { get; init; }
}
