using Microsoft.Data.Sqlite;
using Shouldly;
using Xunit;

namespace ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.Tests;

/// <summary>
///     Verifies <see cref="AlarmConditionStateSchema.Apply"/> creates its table and is idempotent —
///     the DDL depends on nothing but a <see cref="SqliteConnection"/>, so a bare in-memory
///     connection is a faithful harness (no <c>zb_hlc_next()</c> UDF is involved in <c>CREATE TABLE</c>).
/// </summary>
[Trait("Category", "Unit")]
public sealed class AlarmConditionStateSchemaTests
{
    private static SqliteConnection OpenInMemory()
    {
        var connection = new SqliteConnection("Data Source=:memory:");
        connection.Open();
        return connection;
    }

    /// <summary>A single Apply creates the table.</summary>
    [Fact]
    public void Apply_creates_the_state_table()
    {
        using var connection = OpenInMemory();

        AlarmConditionStateSchema.Apply(connection);

        using var cmd = connection.CreateCommand();
        cmd.CommandText =
            "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = @Name";
        cmd.Parameters.AddWithValue("@Name", AlarmConditionStateSchema.StateTable);
        ((long)cmd.ExecuteScalar()!).ShouldBe(1);
    }

    /// <summary>Applying twice on the same connection does not throw (CREATE TABLE IF NOT EXISTS).</summary>
    [Fact]
    public void Apply_is_idempotent()
    {
        using var connection = OpenInMemory();

        AlarmConditionStateSchema.Apply(connection);
        Should.NotThrow(() => AlarmConditionStateSchema.Apply(connection));
    }
}
