using System.Collections.Concurrent;
using ZB.MOM.WW.CBDD.Bson;
using ZB.MOM.WW.CBDD.Shared.TestDbContext_TestDbContext_Mappers;

namespace ZB.MOM.WW.CBDD.Tests;

public class SchemaTests
{
    private static readonly ConcurrentDictionary<string, ushort> _testKeyMap = new(StringComparer.OrdinalIgnoreCase);

    static SchemaTests()
    {
        ushort id = 1;
        foreach (string k in new[]
                     { "_id", "name", "mainaddress", "otheraddresses", "tags", "secret", "street", "city" })
            _testKeyMap[k] = id++;
    }

    /// <summary>
    ///     Executes UsedKeys_ShouldReturnAllKeys.
    /// </summary>
    [Fact]
    public void UsedKeys_ShouldReturnAllKeys()
    {
        var mapper = new ZB_MOM_WW_CBDD_Shared_ComplexUserMapper();
        var keys = mapper.UsedKeys.ToList();

        keys.ShouldContain("_id");
        keys.ShouldContain("name");
        keys.ShouldContain("mainaddress");
        keys.ShouldContain("otheraddresses");
        keys.ShouldContain("tags");
        keys.ShouldContain("secret");
        keys.ShouldContain("street");
        keys.ShouldContain("city");
    }

    /// <summary>
    ///     Executes GetSchema_ShouldReturnBsonSchema.
    /// </summary>
    [Fact]
    public void GetSchema_ShouldReturnBsonSchema()
    {
        var mapper = new ZB_MOM_WW_CBDD_Shared_ComplexUserMapper();
        var schema = mapper.GetSchema();

        var idField = schema.Fields.FirstOrDefault(f => f.Name == "_id");
        idField.ShouldNotBeNull();
        idField.Type.ShouldBe(BsonType.ObjectId);

        var nameField = schema.Fields.FirstOrDefault(f => f.Name == "name");
        nameField.ShouldNotBeNull();
        nameField.Type.ShouldBe(BsonType.String);

        var addressField = schema.Fields.FirstOrDefault(f => f.Name == "mainaddress");
        addressField.ShouldNotBeNull();
        addressField.Type.ShouldBe(BsonType.Document);
        addressField.NestedSchema.ShouldNotBeNull();
        // Address in MockEntities has City (Nested)
        addressField.NestedSchema.Fields.ShouldContain(f => f.Name == "city");
    }
}