using System.Text.Json;
using StellaOps.Feedser.Source.Ru.Nkcki.Internal;
using Xunit;

namespace StellaOps.Feedser.Source.Ru.Nkcki.Tests;

public sealed class RuNkckiJsonParserTests
{
    [Fact]
    public void Parse_WellFormedEntry_ReturnsDto()
    {
        const string json = """
{
  "vuln_id": {"MITRE": "CVE-2025-0001", "FSTEC": "BDU:2025-00001"},
  "date_published": "2025-09-01",
  "date_updated": "2025-09-02",
  "cvss_rating": "КРИТИЧЕСКИЙ",
  "patch_available": true,
  "description": "Test description",
  "cwe": {"cwe_number": 79, "cwe_description": "Cross-site scripting"},
  "product_category": ["Web", "CMS"],
  "mitigation": ["Apply update", "Review configuration"],
  "vulnerable_software": {
    "software_text": "ExampleCMS <= 1.0",
    "software": [{"vendor": "Example", "name": "ExampleCMS", "version": "<= 1.0"}],
    "cpe": false
  },
  "cvss": {
    "cvss_score": 8.8,
    "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
    "cvss_score_v4": 5.5,
    "cvss_vector_v4": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H"
  },
  "impact": "ACE",
  "method_of_exploitation": "Special request",
  "user_interaction": false,
  "urls": ["https://example.com/advisory", {"url": "https://cert.gov.ru/materialy/uyazvimosti/2025-00001"}],
  "tags": ["cms"]
}
""";

        using var document = JsonDocument.Parse(json);
        var dto = RuNkckiJsonParser.Parse(document.RootElement);

        Assert.Equal("BDU:2025-00001", dto.FstecId);
        Assert.Equal("CVE-2025-0001", dto.MitreId);
        Assert.Equal(8.8, dto.CvssScore);
        Assert.Equal("CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", dto.CvssVector);
        Assert.True(dto.PatchAvailable);
        Assert.Equal(79, dto.Cwe?.Number);
        Assert.Contains("Web", dto.ProductCategories);
        Assert.Contains("CMS", dto.ProductCategories);
        Assert.Single(dto.VulnerableSoftwareEntries);
        var entry = dto.VulnerableSoftwareEntries[0];
        Assert.Equal("Example ExampleCMS", entry.Identifier);
        Assert.Contains("<= 1.0", entry.RangeExpressions);
        Assert.Equal(2, dto.Urls.Length);
        Assert.Contains("cms", dto.Tags);
    }
}
