using System.Net;
using ClawdDotNet.Core.Deploymentcenter;
using Shouldly;

namespace ClawdDotNet.Core.Tests.Deploymentcenter;

public sealed class DeploymentcenterApiTests
{
    [Fact]
    public async Task Token_geht_als_Bearer_mit()
    {
        var handler = new CapturingHandler();
        using var api = new DeploymentcenterApi("https://dc.example", "tok-1", new HttpClient(handler));

        await api.PostAsync("/api/health", new { }, default);

        handler.LastRequest!.Headers.Authorization!.ToString().ShouldBe("Bearer tok-1");
    }

    [Fact]
    public async Task Fehlerumschlag_wird_zu_einer_Ausnahme_mit_Code()
    {
        var handler = new CapturingHandler(HttpStatusCode.Unauthorized,
            """{"status":"error","error":{"code":"unauthorized","message":"Kein gueltiges Token."}}""");

        using var api = new DeploymentcenterApi("https://dc.example", "tok", new HttpClient(handler));

        var ex = await Should.ThrowAsync<DeploymentcenterException>(
            () => api.PostAsync("/api/watchdog/v1/ping", new { }, default));

        ex.Code.ShouldBe("unauthorized");
        ex.IsAuthorizationProblem.ShouldBeTrue();
    }

    /// <summary>
    /// Ein Fehlerumschlag zählt auch dann, wenn der Statuscode 200 lautet — der Server
    /// antwortet nicht überall mit passendem HTTP-Code.
    /// </summary>
    [Fact]
    public async Task Fehlerumschlag_mit_HTTP_200_zaehlt_trotzdem()
    {
        var handler = new CapturingHandler(HttpStatusCode.OK,
            """{"status":"error","error":{"code":"rate_limited","message":"Zu viele."}}""");

        using var api = new DeploymentcenterApi("https://dc.example", "tok", new HttpClient(handler));

        var ex = await Should.ThrowAsync<DeploymentcenterException>(
            () => api.PostAsync("/x", new { }, default));

        ex.Code.ShouldBe("rate_limited");
        ex.IsAuthorizationProblem.ShouldBeFalse();
    }

    [Fact]
    public void Nicht_HTTPS_wird_abgelehnt()
    {
        // Über eine ungesicherte Verbindung ginge das Token im Klartext.
        Should.Throw<ArgumentException>(() => new DeploymentcenterApi("http://dc.example", "tok"));
    }

    [Fact]
    public void Localhost_darf_auch_ohne_TLS()
    {
        // Eine lokale Testinstallation hat selten ein Zertifikat, und mithören kann
        // auf dem eigenen Rechner niemand.
        using var api = new DeploymentcenterApi("http://localhost:8080", "tok");
        api.BaseUrl.ShouldBe("http://localhost:8080");
    }
}
