using System.Data;
using Argus.Data;
using Microsoft.EntityFrameworkCore;

namespace Argus.Infrastructure;

public static class SqliteSchemaMigrator
{
    public static async Task EnsureCurrentSchemaAsync(
        ArgusDbContext dbContext,
        CancellationToken cancellationToken = default)
    {
        await dbContext.Database.EnsureCreatedAsync(cancellationToken);

        await ExecuteNonQueryAsync(
            dbContext,
            """
            CREATE INDEX IF NOT EXISTS "IX_Apps_IsListed_Name"
            ON "Apps" ("IsListed", "Name")
            """,
            cancellationToken);

        await ExecuteNonQueryAsync(
            dbContext,
            """
            CREATE INDEX IF NOT EXISTS "IX_Releases_PublishedAt"
            ON "Releases" ("PublishedAt")
            """,
            cancellationToken);

        await ExecuteNonQueryAsync(
            dbContext,
            """
            CREATE INDEX IF NOT EXISTS "IX_Releases_CatalogAppId_PublishedAt"
            ON "Releases" ("CatalogAppId", "PublishedAt")
            """,
            cancellationToken);
    }

    private static async Task ExecuteNonQueryAsync(
        ArgusDbContext dbContext,
        string commandText,
        CancellationToken cancellationToken)
    {
        var connection = dbContext.Database.GetDbConnection();
        var mustClose = connection.State != ConnectionState.Open;

        if (mustClose)
        {
            await connection.OpenAsync(cancellationToken);
        }

        try
        {
            await using var command = connection.CreateCommand();
            command.CommandText = commandText;
            await command.ExecuteNonQueryAsync(cancellationToken);
        }
        finally
        {
            if (mustClose)
            {
                await connection.CloseAsync();
            }
        }
    }
}
