using ZB.MOM.WW.CBDD.Bson;
using ZB.MOM.WW.CBDD.Shared;

namespace ZB.MOM.WW.CBDD.Tests;

public class DocumentCollectionDeleteTests : IDisposable
{
    private readonly TestDbContext _dbContext;
    private readonly string _dbPath;
    private readonly string _walPath;

    /// <summary>
    ///     Initializes a new instance of the <see cref="DocumentCollectionDeleteTests" /> class.
    /// </summary>
    public DocumentCollectionDeleteTests()
    {
        _dbPath = Path.Combine(Path.GetTempPath(), $"test_delete_{Guid.NewGuid()}.db");
        _walPath = Path.Combine(Path.GetTempPath(), $"test_delete_{Guid.NewGuid()}.wal");

        _dbContext = new TestDbContext(_dbPath);
    }

    /// <summary>
    ///     Releases test resources.
    /// </summary>
    public void Dispose()
    {
        _dbContext.Dispose();
    }

    /// <summary>
    ///     Verifies delete removes both the document and its index entry.
    /// </summary>
    [Fact]
    public void Delete_RemovesDocumentAndIndexEntry()
    {
        var user = new User { Id = ObjectId.NewObjectId(), Name = "To Delete", Age = 10 };
        _dbContext.Users.Insert(user);
        _dbContext.SaveChanges();

        // Verify inserted
        _dbContext.Users.FindById(user.Id).ShouldNotBeNull();

        // Delete
        bool deleted = _dbContext.Users.Delete(user.Id);
        _dbContext.SaveChanges();

        // Assert
        deleted.ShouldBeTrue("Delete returned false");

        // Verify deleted from storage
        _dbContext.Users.FindById(user.Id).ShouldBeNull();

        // Verify Index is clean (FindAll uses index scan)
        var all = _dbContext.Users.FindAll();
        all.ShouldBeEmpty();
    }

    /// <summary>
    ///     Verifies delete returns false for a non-existent document.
    /// </summary>
    [Fact]
    public void Delete_NonExistent_ReturnsFalse()
    {
        var id = ObjectId.NewObjectId();
        bool deleted = _dbContext.Users.Delete(id);
        _dbContext.SaveChanges();
        deleted.ShouldBeFalse();
    }

    /// <summary>
    ///     Verifies deletes inside a transaction commit successfully.
    /// </summary>
    [Fact]
    public void Delete_WithTransaction_CommitsSuccessfully()
    {
        var user = new User { Id = ObjectId.NewObjectId(), Name = "Txn Delete", Age = 20 };
        _dbContext.Users.Insert(user);
        _dbContext.SaveChanges();

        using (var txn = _dbContext.BeginTransaction())
        {
            _dbContext.Users.Delete(user.Id);
            _dbContext.SaveChanges();
        }

        // Verify
        _dbContext.Users.FindById(user.Id).ShouldBeNull();
    }
}