using System.Threading;
using ClaudeDo.Ui.Services;
using Xunit;

namespace ClaudeDo.Ui.Tests.Services;

public class PtyTerminalSessionTests
{
    [Fact]
    public async Task WaitForLaunchGateAsync_ThrowsTimeoutException_WhenGateStaysHeld()
    {
        using var gate = new SemaphoreSlim(0, 1); // never released — simulates a hung launch

        await Assert.ThrowsAsync<TimeoutException>(() =>
            PtyTerminalSession.WaitForLaunchGateAsync(gate, TimeSpan.FromMilliseconds(50), CancellationToken.None));
    }

    [Fact]
    public async Task WaitForLaunchGateAsync_DoesNotReleaseGate_ItNeverAcquired()
    {
        using var gate = new SemaphoreSlim(0, 1);

        await Assert.ThrowsAsync<TimeoutException>(() =>
            PtyTerminalSession.WaitForLaunchGateAsync(gate, TimeSpan.FromMilliseconds(50), CancellationToken.None));

        Assert.Equal(0, gate.CurrentCount); // still held; a bad fix would Release() what it never acquired
    }

    [Fact]
    public async Task WaitForLaunchGateAsync_AcquiresGate_WhenAvailable()
    {
        using var gate = new SemaphoreSlim(1, 1);

        await PtyTerminalSession.WaitForLaunchGateAsync(gate, TimeSpan.FromSeconds(5), CancellationToken.None);

        Assert.Equal(0, gate.CurrentCount); // acquired
    }
}
