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

namespace StellaOps.Feedser.Source.Osv.Internal;

internal sealed record OsvVulnerabilityDto
{
    [JsonPropertyName("id")]
    public string Id { get; init; } = string.Empty;

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

    [JsonPropertyName("details")]
    public string? Details { get; init; }

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

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

    [JsonPropertyName("published")]
    public DateTimeOffset? Published { get; init; }

    [JsonPropertyName("modified")]
    public DateTimeOffset? Modified { get; init; }

    [JsonPropertyName("severity")]
    public IReadOnlyList<OsvSeverityDto>? Severity { get; init; }

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

    [JsonPropertyName("affected")]
    public IReadOnlyList<OsvAffectedPackageDto>? Affected { get; init; }

    [JsonPropertyName("credits")]
    public IReadOnlyList<OsvCreditDto>? Credits { get; init; }

    [JsonPropertyName("database_specific")]
    public JsonElement DatabaseSpecific { get; init; }
}

internal sealed record OsvSeverityDto
{
    [JsonPropertyName("type")]
    public string? Type { get; init; }

    [JsonPropertyName("score")]
    public string? Score { get; init; }
}

internal sealed record OsvReferenceDto
{
    [JsonPropertyName("type")]
    public string? Type { get; init; }

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

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

    [JsonPropertyName("type")]
    public string? Type { get; init; }

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

internal sealed record OsvAffectedPackageDto
{
    [JsonPropertyName("package")]
    public OsvPackageDto? Package { get; init; }

    [JsonPropertyName("ranges")]
    public IReadOnlyList<OsvRangeDto>? Ranges { get; init; }

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

    [JsonPropertyName("ecosystem_specific")]
    public JsonElement EcosystemSpecific { get; init; }
}

internal sealed record OsvPackageDto
{
    [JsonPropertyName("ecosystem")]
    public string? Ecosystem { get; init; }

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

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

internal sealed record OsvRangeDto
{
    [JsonPropertyName("type")]
    public string? Type { get; init; }

    [JsonPropertyName("events")]
    public IReadOnlyList<OsvEventDto>? Events { get; init; }

    [JsonPropertyName("repo")]
    public string? Repository { get; init; }
}

internal sealed record OsvEventDto
{
    [JsonPropertyName("introduced")]
    public string? Introduced { get; init; }

    [JsonPropertyName("fixed")]
    public string? Fixed { get; init; }

    [JsonPropertyName("last_affected")]
    public string? LastAffected { get; init; }

    [JsonPropertyName("limit")]
    public string? Limit { get; init; }
}
