using ScadaLink.Commons.Entities.ExternalSystems;

namespace ScadaLink.Commons.Interfaces.Repositories;

public interface IExternalSystemRepository
{
    // ExternalSystemDefinition
    Task<ExternalSystemDefinition?> GetExternalSystemByIdAsync(int id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Returns the external system with the given name, or <c>null</c> if no such
    /// system exists. A name-keyed lookup so hot-path resolution (e.g. a script's
    /// <c>ExternalSystem.Call()</c>) does not have to fetch every system and filter
    /// in memory on each call (ExternalSystemGateway-011).
    /// </summary>
    Task<ExternalSystemDefinition?> GetExternalSystemByNameAsync(string name, CancellationToken cancellationToken = default);

    Task<IReadOnlyList<ExternalSystemDefinition>> GetAllExternalSystemsAsync(CancellationToken cancellationToken = default);
    Task AddExternalSystemAsync(ExternalSystemDefinition definition, CancellationToken cancellationToken = default);
    Task UpdateExternalSystemAsync(ExternalSystemDefinition definition, CancellationToken cancellationToken = default);
    Task DeleteExternalSystemAsync(int id, CancellationToken cancellationToken = default);

    // ExternalSystemMethod
    Task<ExternalSystemMethod?> GetExternalSystemMethodByIdAsync(int id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Returns the method with the given name belonging to the given external system,
    /// or <c>null</c> if no such method exists. A name-keyed lookup so hot-path
    /// resolution does not have to fetch every method of the system and filter in
    /// memory on each call (ExternalSystemGateway-011).
    /// </summary>
    Task<ExternalSystemMethod?> GetMethodByNameAsync(int externalSystemId, string methodName, CancellationToken cancellationToken = default);

    Task<IReadOnlyList<ExternalSystemMethod>> GetMethodsByExternalSystemIdAsync(int externalSystemId, CancellationToken cancellationToken = default);
    Task AddExternalSystemMethodAsync(ExternalSystemMethod method, CancellationToken cancellationToken = default);
    Task UpdateExternalSystemMethodAsync(ExternalSystemMethod method, CancellationToken cancellationToken = default);
    Task DeleteExternalSystemMethodAsync(int id, CancellationToken cancellationToken = default);

    // DatabaseConnectionDefinition
    Task<DatabaseConnectionDefinition?> GetDatabaseConnectionByIdAsync(int id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Returns the database connection definition with the given name, or <c>null</c>
    /// if no such connection exists. A name-keyed lookup so hot-path resolution (e.g.
    /// a script's <c>Database.Connection()</c> / <c>Database.CachedWrite()</c>) does
    /// not have to fetch every connection and filter in memory on each call
    /// (ExternalSystemGateway-011).
    /// </summary>
    Task<DatabaseConnectionDefinition?> GetDatabaseConnectionByNameAsync(string name, CancellationToken cancellationToken = default);

    Task<IReadOnlyList<DatabaseConnectionDefinition>> GetAllDatabaseConnectionsAsync(CancellationToken cancellationToken = default);
    Task AddDatabaseConnectionAsync(DatabaseConnectionDefinition definition, CancellationToken cancellationToken = default);
    Task UpdateDatabaseConnectionAsync(DatabaseConnectionDefinition definition, CancellationToken cancellationToken = default);
    Task DeleteDatabaseConnectionAsync(int id, CancellationToken cancellationToken = default);

    Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
