using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Excititor.Connectors.Abstractions;
using StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Configuration;
using StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Discovery;
using StellaOps.Excititor.Core;
using System.Collections.Generic;
using System.IO.Abstractions.TestingHelpers;
using Xunit;

namespace StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests.Configuration;

public sealed class OciOpenVexAttestationConnectorOptionsValidatorTests
{
    [Fact]
    public void Validate_WithValidConfiguration_Succeeds()
    {
        var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
        {
            ["/offline/registry.example.com/repo/latest/openvex-attestations.tgz"] = new MockFileData(string.Empty),
        });

        var validator = new OciOpenVexAttestationConnectorOptionsValidator(fileSystem);
        var options = new OciOpenVexAttestationConnectorOptions
        {
            AllowHttpRegistries = true,
        };

        options.Images.Add(new OciImageSubscriptionOptions
        {
            Reference = "registry.example.com/repo/image:latest",
            OfflineBundlePath = "/offline/registry.example.com/repo/latest/openvex-attestations.tgz",
        });

        options.Registry.Username = "user";
        options.Registry.Password = "pass";

        options.Cosign.Mode = CosignCredentialMode.None;

        var errors = new List<string>();

        validator.Validate(new VexConnectorDescriptor("id", VexProviderKind.Attestation, "display"), options, errors);

        errors.Should().BeEmpty();
    }

    [Fact]
    public void Validate_WhenImagesMissing_AddsError()
    {
        var validator = new OciOpenVexAttestationConnectorOptionsValidator(new MockFileSystem());
        var options = new OciOpenVexAttestationConnectorOptions();

        var errors = new List<string>();

        validator.Validate(new VexConnectorDescriptor("id", VexProviderKind.Attestation, "display"), options, errors);

        errors.Should().ContainSingle().Which.Should().Contain("At least one OCI image reference must be configured.");
    }

    [Fact]
    public void Validate_WhenDigestMalformed_AddsError()
    {
        var validator = new OciOpenVexAttestationConnectorOptionsValidator(new MockFileSystem());
        var options = new OciOpenVexAttestationConnectorOptions();
        options.Images.Add(new OciImageSubscriptionOptions
        {
            Reference = "registry.test/repo/image@sha256:not-a-digest",
        });

        var errors = new List<string>();

        validator.Validate(new VexConnectorDescriptor("id", VexProviderKind.Attestation, "display"), options, errors);

        errors.Should().ContainSingle();
    }
}
