using System.Data.Common;
using ZB.MOM.WW.ScadaBridge.Commons.Types;

namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;

/// <summary>
/// Interface for database access from scripts.
/// Implemented by ExternalSystemGateway, consumed by ScriptRuntimeContext.
/// </summary>
public interface IDatabaseGateway
{
    /// <summary>
    /// Returns an ADO.NET DbConnection (typically SqlConnection) from the named connection.
    /// Connection pooling is managed by the underlying provider.
    /// Caller is responsible for disposing.
    /// </summary>
    /// <param name="connectionName">Name of the configured database connection to open.</param>
    /// <param name="cancellationToken">Cancellation token for the async open operation.</param>
    /// <returns>A task that resolves to an open <see cref="DbConnection"/>; the caller is responsible for disposing it.</returns>
    Task<DbConnection> GetConnectionAsync(
        string connectionName,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Submits a SQL write to the store-and-forward engine for reliable delivery.
    /// </summary>
    /// <param name="trackedOperationId">
    /// Audit Log #23 (M3): caller-supplied tracking id used as the
    /// store-and-forward message id so the S&amp;F retry loop can read it
    /// back via <c>StoreAndForwardMessage.Id</c> and emit per-attempt /
    /// terminal cached-write telemetry under the same id. Defaults to
    /// <c>null</c> — when omitted the S&amp;F engine mints a fresh GUID and no
    /// M3 telemetry is correlated (pre-M3 caller behaviour).
    /// </param>
    /// <param name="executionId">
    /// Audit Log #23 (ExecutionId Task 4): the originating script execution's
    /// per-run correlation id. When the write is buffered on a transient
    /// failure this is threaded onto the S&amp;F message so the retry-loop
    /// cached-write audit rows carry it. <c>null</c> when not threaded.
    /// </param>
    /// <param name="sourceScript">
    /// Audit Log #23 (ExecutionId Task 4): the originating script identifier,
    /// threaded onto the buffered S&amp;F message alongside
    /// <paramref name="executionId"/>. <c>null</c> when not known.
    /// </param>
    /// <param name="parentExecutionId">
    /// Audit Log #23 (ParentExecutionId Task 6): the <c>ExecutionId</c> of the
    /// inbound-API request that spawned the originating script execution.
    /// When the write is buffered on a transient failure this is threaded onto
    /// the S&amp;F message alongside <paramref name="executionId"/> so the
    /// retry-loop cached-write audit rows carry it. <c>null</c> for a
    /// non-routed run.
    /// </param>
    /// <param name="connectionName">Name of the configured database connection to write to.</param>
    /// <param name="sql">SQL statement to execute as a store-and-forward write.</param>
    /// <param name="parameters">Optional SQL parameters for the statement.</param>
    /// <param name="originInstanceName">Optional name of the instance that originated the write.</param>
    /// <param name="cancellationToken">Cancellation token for the buffering operation.</param>
    /// <returns>A task that represents the asynchronous operation.</returns>
    Task CachedWriteAsync(
        string connectionName,
        string sql,
        IReadOnlyDictionary<string, object?>? parameters = null,
        string? originInstanceName = null,
        CancellationToken cancellationToken = default,
        TrackedOperationId? trackedOperationId = null,
        Guid? executionId = null,
        string? sourceScript = null,
        Guid? parentExecutionId = null);
}
