using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Planning;
using ClaudeDo.Worker.Runner;
using ClaudeDo.Worker.Tests.Infrastructure;
using Microsoft.AspNetCore.Http;
using Xunit;

namespace ClaudeDo.Worker.Tests.Hub;

public sealed class TaskRunTokenAuthTests : IDisposable
{
    private readonly DbFixture _db = new();
    public void Dispose() => _db.Dispose();

    [Fact]
    public async Task Valid_taskRun_token_populates_TaskRunContext_and_calls_next()
    {
        var reg = new TaskRunTokenRegistry();
        reg.Register("run-token", "task-1");
        bool nextCalled = false;
        var mw = new PlanningTokenAuthMiddleware(_ => { nextCalled = true; return Task.CompletedTask; });
        var ctx = new DefaultHttpContext();
        ctx.Request.Path = "/mcp";
        ctx.Request.Headers["Authorization"] = "Bearer run-token";
        using var db = _db.CreateContext();
        await mw.InvokeAsync(ctx, new TaskRepository(db), reg);
        Assert.True(nextCalled);
        var resolved = ctx.Items["TaskRunContext"] as TaskRunMcpContext;
        Assert.NotNull(resolved);
        Assert.Equal("task-1", resolved!.CallerTaskId);
    }

    [Fact]
    public async Task Unknown_token_returns_401()
    {
        var mw = new PlanningTokenAuthMiddleware(_ => Task.CompletedTask);
        var ctx = new DefaultHttpContext();
        ctx.Request.Path = "/mcp";
        ctx.Request.Headers["Authorization"] = "Bearer nope";
        using var db = _db.CreateContext();
        await mw.InvokeAsync(ctx, new TaskRepository(db), new TaskRunTokenRegistry());
        Assert.Equal(401, ctx.Response.StatusCode);
    }
}
