namespace DodoSSH.Client.Sync.Tests;

/// <summary>
/// The id a rescued item takes.
/// </summary>
/// <remarks>
/// Determinism here is what makes the rescue crash-safe. The reconciler queues the restored copy before
/// it clears the original, and those are two separate transactions — so a process that dies between them
/// leaves the original pending and resurrects again on the next pass. Landing on the same id means that
/// second attempt coalesces into the row already queued instead of leaving the user with duplicates.
/// </remarks>
public sealed class ResurrectionIdTests
{
    private static readonly Guid Original = Guid.Parse("0192f0c8-1234-7c3d-8e4f-5a6b7c8d9e0f");

    private static readonly Guid Other = Guid.Parse("0192f0c8-5678-7c3d-8e4f-5a6b7c8d9e0f");

    [Fact]
    public void TheSameTombstone_AlwaysYieldsTheSameId()
    {
        ResurrectionId.For(Original, 3).ShouldBe(ResurrectionId.For(Original, 3));
    }

    [Fact]
    public void ADifferentItem_YieldsADifferentId()
    {
        ResurrectionId.For(Original, 3).ShouldNotBe(ResurrectionId.For(Other, 3));
    }

    [Fact]
    public void ADifferentTombstoneVersion_YieldsADifferentId()
    {
        // An item deleted, restored, and deleted again must produce a second rescue rather than
        // colliding with the first.
        ResurrectionId.For(Original, 3).ShouldNotBe(ResurrectionId.For(Original, 4));
    }

    [Fact]
    public void TheIdIsNotTheOriginal()
    {
        // The tombstone stands, so the rescued copy has to be a different item. Reusing the id would
        // conflict against the tombstone for ever.
        ResurrectionId.For(Original, 1).ShouldNotBe(Original);
        ResurrectionId.For(Original, 1).ShouldNotBe(Guid.Empty);
    }
}
