using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Scanner.Sbomer.BuildXPlugin.Descriptor;

namespace StellaOps.Scanner.Sbomer.BuildXPlugin.Attestation;

/// <summary>
/// Sends provenance placeholders to the Attestor service for asynchronous DSSE signing.
/// </summary>
public sealed class AttestorClient
{
    private readonly HttpClient httpClient;

    public AttestorClient(HttpClient httpClient)
    {
        this.httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
    }

    public async Task SendPlaceholderAsync(Uri attestorUri, DescriptorDocument document, CancellationToken cancellationToken)
    {
        if (attestorUri is null)
        {
            throw new ArgumentNullException(nameof(attestorUri));
        }

        if (document is null)
        {
            throw new ArgumentNullException(nameof(document));
        }

        var payload = new AttestorProvenanceRequest(
            ImageDigest: document.Subject.Digest,
            SbomDigest: document.Artifact.Digest,
            ExpectedDsseSha256: document.Provenance.ExpectedDsseSha256,
            Nonce: document.Provenance.Nonce,
            PredicateType: document.Provenance.PredicateType,
            Schema: document.Schema);

        using var response = await httpClient.PostAsJsonAsync(attestorUri, payload, cancellationToken).ConfigureAwait(false);
        if (!response.IsSuccessStatusCode)
        {
            var body = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
            throw new BuildxPluginException($"Attestor rejected provenance placeholder ({(int)response.StatusCode}): {body}");
        }
    }
}
