using ZB.MOM.WW.CBDD.Bson;
using ZB.MOM.WW.CBDD.Bson.IO;
using ZB.MOM.WW.CBDD.Bson.Schema;
using ZB.MOM.WW.CBDD.Core.Indexing;

namespace ZB.MOM.WW.CBDD.Core.Collections;

/// <summary>
///     Non-generic interface for common mapper operations.
/// </summary>
public interface IDocumentMapper
{
    /// <summary>
    ///     Gets the collection name handled by this mapper.
    /// </summary>
    string CollectionName { get; }

    /// <summary>
    ///     Gets the set of document keys used during mapping.
    /// </summary>
    IEnumerable<string> UsedKeys { get; }

    /// <summary>
    ///     Gets the BSON schema for the mapped document.
    /// </summary>
    /// <returns>The BSON schema.</returns>
    BsonSchema GetSchema();
}

/// <summary>
///     Interface for mapping between entities and BSON using zero-allocation serialization.
///     Handles bidirectional mapping between TId and IndexKey.
/// </summary>
public interface IDocumentMapper<TId, T> : IDocumentMapper where T : class
{
    /// <summary>
    ///     Serializes an entity to BSON.
    /// </summary>
    /// <param name="entity">The entity to serialize.</param>
    /// <param name="writer">The BSON writer.</param>
    /// <returns>The number of bytes written.</returns>
    int Serialize(T entity, BsonSpanWriter writer);

    /// <summary>
    ///     Deserializes an entity from BSON.
    /// </summary>
    /// <param name="reader">The BSON reader.</param>
    /// <returns>The deserialized entity.</returns>
    T Deserialize(BsonSpanReader reader);

    /// <summary>
    ///     Gets the identifier value from an entity.
    /// </summary>
    /// <param name="entity">The entity.</param>
    /// <returns>The identifier value.</returns>
    TId GetId(T entity);

    /// <summary>
    ///     Sets the identifier value on an entity.
    /// </summary>
    /// <param name="entity">The entity.</param>
    /// <param name="id">The identifier value.</param>
    void SetId(T entity, TId id);

    /// <summary>
    ///     Converts an identifier to an index key.
    /// </summary>
    /// <param name="id">The identifier value.</param>
    /// <returns>The index key representation.</returns>
    IndexKey ToIndexKey(TId id);

    /// <summary>
    ///     Converts an index key back to an identifier.
    /// </summary>
    /// <param name="key">The index key.</param>
    /// <returns>The identifier value.</returns>
    TId FromIndexKey(IndexKey key);
}

/// <summary>
///     Legacy interface for compatibility with existing ObjectId-based collections.
/// </summary>
public interface IDocumentMapper<T> : IDocumentMapper<ObjectId, T> where T : class
{
}