using System.Net;
using System.Text.Json;

namespace Tiku.IntegrationTests.Api;

public sealed class OpenApiDocumentationTests
{
    [Fact]
    public async Task Openapi_document_can_be_generated_with_key_paths()
    {
        await using var factory = new ApiTestFactory();
        using var client = factory.CreateClient();

        using var response = await client.GetAsync("/openapi/v1.json");
        var document = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        Assert.True(document.RootElement.GetProperty("paths").TryGetProperty("/api/tenant/auth/login/password", out _));
        Assert.True(document.RootElement.GetProperty("paths").TryGetProperty("/api/public/catalog/regions", out _));
    }

    [Fact]
    public async Task Platform_operation_metadata_prefers_action_permission_and_exposes_risk()
    {
        await using var factory = new ApiTestFactory();
        using var client = factory.CreateClient();

        using var response = await client.GetAsync("/openapi/v1.json");
        using var document = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        var operation = document.RootElement.GetProperty("paths")
            .GetProperty("/api/platform/approvals/{requestId}/approve")
            .GetProperty("post");

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        Assert.Equal("platform:approval:decide", operation.GetProperty("x-tiku-required-permission").GetString());
        Assert.Equal("high", operation.GetProperty("x-tiku-risk-level").GetString());
    }

    [Fact]
    public async Task Openapi_uses_role_scoped_routes_without_legacy_prefixes()
    {
        await using var factory = new ApiTestFactory();
        using var client = factory.CreateClient();

        using var response = await client.GetAsync("/openapi/v1.json");
        using var document = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        var paths = document.RootElement.GetProperty("paths").EnumerateObject()
            .Select(item => item.Name)
            .ToArray();

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        Assert.Contains(paths, path => path.StartsWith("/api/platform/", StringComparison.Ordinal));
        Assert.Contains(paths, path => path.StartsWith("/api/tenant/", StringComparison.Ordinal));
        Assert.Contains(paths, path => path.StartsWith("/api/student/", StringComparison.Ordinal));
        Assert.Contains(paths, path => path.StartsWith("/api/public/", StringComparison.Ordinal));
        Assert.Contains(paths, path => path.StartsWith("/api/system/", StringComparison.Ordinal));
        Assert.DoesNotContain(paths, path =>
            path.StartsWith("/api/platform-admin", StringComparison.Ordinal) ||
            path.StartsWith("/api/backoffice/", StringComparison.Ordinal) ||
            path.StartsWith("/api/tenant-admin", StringComparison.Ordinal) ||
            path.StartsWith("/api/tenant-content", StringComparison.Ordinal) ||
            path.StartsWith("/api/tenant-commerce", StringComparison.Ordinal));
    }
}