using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
using StellaOps.Excititor.Connectors.Abstractions;
using StellaOps.Excititor.Connectors.Ubuntu.CSAF.Configuration;
using StellaOps.Excititor.Connectors.Ubuntu.CSAF.Metadata;
using StellaOps.Excititor.Core;

namespace StellaOps.Excititor.Connectors.Ubuntu.CSAF;

public sealed class UbuntuCsafConnector : VexConnectorBase
{
    private static readonly VexConnectorDescriptor DescriptorInstance = new(
        id: "excititor:ubuntu",
        kind: VexProviderKind.Distro,
        displayName: "Ubuntu CSAF")
    {
        Tags = ImmutableArray.Create("ubuntu", "csaf", "usn"),
    };

    private readonly UbuntuCatalogLoader _catalogLoader;
    private readonly IEnumerable<IVexConnectorOptionsValidator<UbuntuConnectorOptions>> _validators;

    private UbuntuConnectorOptions? _options;
    private UbuntuCatalogResult? _catalog;

    public UbuntuCsafConnector(
        UbuntuCatalogLoader catalogLoader,
        IEnumerable<IVexConnectorOptionsValidator<UbuntuConnectorOptions>> validators,
        ILogger<UbuntuCsafConnector> logger,
        TimeProvider timeProvider)
        : base(DescriptorInstance, logger, timeProvider)
    {
        _catalogLoader = catalogLoader ?? throw new ArgumentNullException(nameof(catalogLoader));
        _validators = validators ?? Array.Empty<IVexConnectorOptionsValidator<UbuntuConnectorOptions>>();
    }

    public override async ValueTask ValidateAsync(VexConnectorSettings settings, CancellationToken cancellationToken)
    {
        _options = VexConnectorOptionsBinder.Bind(
            Descriptor,
            settings,
            validators: _validators);

        _catalog = await _catalogLoader.LoadAsync(_options, cancellationToken).ConfigureAwait(false);
        LogConnectorEvent(LogLevel.Information, "validate", "Ubuntu CSAF index loaded.", new Dictionary<string, object?>
        {
            ["channelCount"] = _catalog.Metadata.Channels.Length,
            ["fromOffline"] = _catalog.FromOfflineSnapshot,
        });
    }

    public override async IAsyncEnumerable<VexRawDocument> FetchAsync(VexConnectorContext context, [EnumeratorCancellation] CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(context);

        if (_options is null)
        {
            throw new InvalidOperationException("Connector must be validated before fetch operations.");
        }

        if (_catalog is null)
        {
            _catalog = await _catalogLoader.LoadAsync(_options, cancellationToken).ConfigureAwait(false);
        }

        LogConnectorEvent(LogLevel.Debug, "fetch", "Ubuntu CSAF discovery ready; channel catalogs handled in subsequent task.", new Dictionary<string, object?>
        {
            ["since"] = context.Since?.ToString("O"),
        });

        yield break;
    }

    public override ValueTask<VexClaimBatch> NormalizeAsync(VexRawDocument document, CancellationToken cancellationToken)
        => throw new NotSupportedException("UbuntuCsafConnector relies on CSAF normalizers for document processing.");

    public UbuntuCatalogResult? GetCachedCatalog() => _catalog;
}
