using System.Data;

namespace TakeoutSaaS.Shared.Abstractions.Data;

/// <summary>
/// Dapper 查询/命令执行器抽象，封装连接获取与读写路由。
/// </summary>
public interface IDapperExecutor
{
    /// <summary>
    /// 使用指定数据源与读写角色执行异步查询，并返回结果。
    /// </summary>
    /// <typeparam name="TResult">查询结果类型。</typeparam>
    /// <param name="dataSourceName">逻辑数据源名称。</param>
    /// <param name="role">连接角色（读/写）。</param>
    /// <param name="query">查询委托，提供已打开的连接和取消标记。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>查询结果。</returns>
    Task<TResult> QueryAsync<TResult>(
        string dataSourceName,
        DatabaseConnectionRole role,
        Func<IDbConnection, CancellationToken, Task<TResult>> query,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 使用指定数据源与读写角色执行异步命令。
    /// </summary>
    /// <param name="dataSourceName">逻辑数据源名称。</param>
    /// <param name="role">连接角色（读/写）。</param>
    /// <param name="command">命令委托，提供已打开的连接和取消标记。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步执行任务。</returns>
    Task ExecuteAsync(
        string dataSourceName,
        DatabaseConnectionRole role,
        Func<IDbConnection, CancellationToken, Task> command,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取指定数据源及角色的默认命令超时时间（秒）。
    /// </summary>
    /// <param name="dataSourceName">逻辑数据源名称。</param>
    /// <param name="role">连接角色，默认读取从库。</param>
    /// <returns>命令超时时间（秒）。</returns>
    int GetDefaultCommandTimeoutSeconds(
        string dataSourceName,
        DatabaseConnectionRole role = DatabaseConnectionRole.Read);
}
