using System.IO;
using System.Xml.Linq;
using StellaOps.Feedser.Source.Ru.Bdu.Internal;
using Xunit;

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

public sealed class RuBduXmlParserTests
{
    [Fact]
    public void TryParse_ValidElement_ReturnsDto()
    {
        const string xml = """
<vul>
  <identifier>BDU:2025-12345</identifier>
  <name>Уязвимость тестового продукта</name>
  <description>Описание уязвимости</description>
  <solution>Обновить продукт</solution>
  <identify_date>2025-10-10</identify_date>
  <severity>Высокий уровень опасности</severity>
  <exploit_status>Существует эксплойт</exploit_status>
  <fix_status>Устранена</fix_status>
  <vul_status>Подтверждена производителем</vul_status>
  <vul_incident>1</vul_incident>
  <cvss>
    <vector score="7.5">AV:N/AC:L/Au:N/C:P/I:P/A:P</vector>
  </cvss>
  <cvss3>
    <vector score="9.8">AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H</vector>
  </cvss3>
  <vulnerable_software>
    <soft>
      <vendor>ООО «Вендор»</vendor>
      <name>Продукт</name>
      <version>1.2.3</version>
      <platform>Windows</platform>
      <types>
        <type>ics</type>
      </types>
    </soft>
  </vulnerable_software>
  <sources>
    https://advisories.example/BDU-2025-12345
    https://mirror.example/ru-bdu/BDU-2025-12345
  </sources>
  <identifiers>
    <identifier type="CVE" link="https://nvd.nist.gov/vuln/detail/CVE-2025-12345">CVE-2025-12345</identifier>
    <identifier type="GHSA" link="https://github.com/advisories/GHSA-xxxx-yyyy-zzzz">GHSA-xxxx-yyyy-zzzz</identifier>
  </identifiers>
  <cwes>
    <cwe>
      <identifier>CWE-79</identifier>
      <name>XSS</name>
    </cwe>
  </cwes>
</vul>
""";

        var element = XElement.Parse(xml);
        var dto = RuBduXmlParser.TryParse(element);

        Assert.NotNull(dto);
        Assert.Equal("BDU:2025-12345", dto!.Identifier);
        Assert.Equal("Уязвимость тестового продукта", dto.Name);
        Assert.Equal("AV:N/AC:L/Au:N/C:P/I:P/A:P", dto.CvssVector);
        Assert.Equal(7.5, dto.CvssScore);
        Assert.Equal("AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", dto.Cvss3Vector);
        Assert.Equal(9.8, dto.Cvss3Score);
        Assert.Single(dto.Software);
        Assert.Single(dto.Cwes);
        Assert.Equal(2, dto.Sources.Length);
        Assert.Contains("https://advisories.example/BDU-2025-12345", dto.Sources);
        Assert.Equal(2, dto.Identifiers.Length);
        Assert.Contains(dto.Identifiers, identifier => identifier.Type == "CVE" && identifier.Value == "CVE-2025-12345");
        Assert.Contains(dto.Identifiers, identifier => identifier.Type == "GHSA" && identifier.Link == "https://github.com/advisories/GHSA-xxxx-yyyy-zzzz");
    }

    [Fact]
    public void TryParse_SampleArchiveEntries_ReturnDtos()
    {
        var path = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "Fixtures", "export-sample.xml"));
        var document = XDocument.Load(path);
        var vulnerabilities = document.Root?.Elements("vul");
        Assert.NotNull(vulnerabilities);

        foreach (var element in vulnerabilities!)
        {
            var dto = RuBduXmlParser.TryParse(element);
            Assert.NotNull(dto);
            Assert.False(string.IsNullOrWhiteSpace(dto!.Identifier));
        }
    }
}
