using Lumi.Companion.Core;

static void Assert(bool condition, string message)
{
    if (!condition) throw new InvalidOperationException(message);
}

var operation = new SingleFlightOperation();
var calls = 0;
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
Assert(calls == 1 && !operation.IsRunning, "A successful update-style operation did not reset.");

await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
Assert(calls == 2 && !operation.IsRunning, "A no-update-style repeat did not execute.");

try
{
    await operation.RunAsync(_ => throw new InvalidOperationException("expected"));
}
catch (InvalidOperationException error) when (error.Message == "expected") { }
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
Assert(calls == 3 && !operation.IsRunning, "A failed operation left stale single-flight state.");

using (var cancelled = new CancellationTokenSource())
{
    cancelled.Cancel();
    try { await operation.RunAsync(token => Task.Delay(1, token), cancelled.Token); }
    catch (OperationCanceledException) { }
}
await operation.RunAsync(_ => { calls += 1; return Task.CompletedTask; });
Assert(calls == 4 && !operation.IsRunning, "A cancelled operation left stale single-flight state.");

var release = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var concurrentCalls = 0;
var first = operation.RunAsync(async _ => { concurrentCalls += 1; await release.Task; });
var second = operation.RunAsync(async _ => { concurrentCalls += 1; await Task.Yield(); });
Assert(operation.IsRunning && concurrentCalls == 1, "Rapid update checks started more than one operation.");
release.SetResult();
await Task.WhenAll(first, second);
Assert(concurrentCalls == 1 && !operation.IsRunning, "Rapid update checks did not share and reset the active operation.");

Console.WriteLine("Companion core single-flight regression checks passed.");
