using DodoSSH.Client.Domain;
using DodoSSH.Client.Storage;

namespace DodoSSH.Client.Sync;

/// <summary>
/// The credentials in a vault, decrypted, with unpushed local changes laid over them.
/// </summary>
/// <remarks>
/// <para>
/// The third facade over the same generic repository, and by now that is the point: adding an item type to
/// this client is a kind, a facade and a view, with no new reconciliation logic and no new sync path.
/// </para>
/// <para>
/// <b>A credential listed here has its password in memory.</b> Listing decrypts every credential in the
/// vault, so the caller holds them all for as long as it holds the listing — the same bargain
/// <see cref="SshKeyRepository"/> makes for key material, and worth restating because it is the reason the
/// interface reads a listing once per reload rather than holding one open.
/// </para>
/// </remarks>
public sealed class CredentialRepository(
    ItemStore items,
    OutboxStore outbox,
    VaultKeyring keyring,
    IActivityLogSink? activity = null)
{
    private readonly VaultItemRepository<CredentialSecret> credentials =
        new(CredentialKind.Instance, items, outbox, keyring, activity);

    /// <inheritdoc cref="VaultItemRepository{TSecret}.ListAsync" />
    public Task<ItemListing<CredentialSecret>> ListAsync(
        Guid vaultId,
        CancellationToken cancellationToken) =>
        credentials.ListAsync(vaultId, cancellationToken);

    /// <inheritdoc cref="VaultItemRepository{TSecret}.CreateAsync" />
    public Task<Guid> CreateAsync(
        Guid vaultId,
        CredentialSecret credential,
        CancellationToken cancellationToken) =>
        credentials.CreateAsync(vaultId, credential, cancellationToken);

    /// <inheritdoc cref="VaultItemRepository{TSecret}.UpdateAsync" />
    public Task UpdateAsync(
        Guid vaultId,
        Guid entityId,
        CredentialSecret credential,
        CancellationToken cancellationToken) =>
        credentials.UpdateAsync(vaultId, entityId, credential, cancellationToken);

    /// <inheritdoc cref="VaultItemRepository{TSecret}.MoveAsync" />
    /// <inheritdoc cref="SshKeyRepository.MoveAsync" path="/remarks" />
    public Task<Guid> MoveAsync(
        Guid fromVaultId,
        Guid toVaultId,
        Guid entityId,
        CredentialSecret credential,
        CancellationToken cancellationToken) =>
        credentials.MoveAsync(fromVaultId, toVaultId, entityId, credential, cancellationToken);

    /// <inheritdoc cref="VaultItemRepository{TSecret}.DeleteAsync" />
    public Task DeleteAsync(Guid vaultId, Guid entityId, CancellationToken cancellationToken) =>
        credentials.DeleteAsync(vaultId, entityId, cancellationToken);
}
