using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Feedser.Source.Vndr.Cisco.Internal;
using Xunit;

namespace StellaOps.Feedser.Source.Vndr.Cisco.Tests;

public sealed class CiscoDtoFactoryTests
{
    [Fact]
    public async Task CreateAsync_MergesRawAndCsafProducts()
    {
        const string CsafPayload = @"
{
  ""product_tree"": {
    ""full_product_names"": [
      { ""product_id"": ""PID-1"", ""name"": ""Cisco Widget"" }
    ]
  },
  ""vulnerabilities"": [
    {
      ""product_status"": {
        ""known_affected"": [""PID-1""]
      }
    }
  ]
}";

        var csafClient = new StubCsafClient(CsafPayload);
        var factory = new CiscoDtoFactory(csafClient, NullLogger<CiscoDtoFactory>.Instance);

        var raw = new CiscoRawAdvisory
        {
            AdvisoryId = "CISCO-SA-TEST",
            AdvisoryTitle = "Test Advisory",
            Summary = "Summary",
            Sir = "High",
            FirstPublished = "2025-10-01T00:00:00Z",
            LastUpdated = "2025-10-02T00:00:00Z",
            PublicationUrl = "https://example.com/advisory",
            CsafUrl = "https://sec.cloudapps.cisco.com/csaf/test.json",
            Cves = new List<string> { "CVE-2024-0001" },
            BugIds = new List<string> { "BUG123" },
            ProductNames = new List<string> { "Cisco Widget" },
            Version = "1.2.3",
            CvssBaseScore = "9.8"
        };

        var dto = await factory.CreateAsync(raw, CancellationToken.None);

        dto.Should().NotBeNull();
        dto.Severity.Should().Be("high");
        dto.CvssBaseScore.Should().Be(9.8);
        dto.Products.Should().HaveCount(1);
        var product = dto.Products[0];
        product.Name.Should().Be("Cisco Widget");
        product.ProductId.Should().Be("PID-1");
        product.Statuses.Should().Contain("known_affected");
    }

    private sealed class StubCsafClient : ICiscoCsafClient
    {
        private readonly string? _payload;

        public StubCsafClient(string? payload) => _payload = payload;

        public Task<string?> TryFetchAsync(string? url, CancellationToken cancellationToken)
            => Task.FromResult(_payload);
    }
}
