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

namespace DodoSSH.Client.Sync;

/// <summary>
/// The tags in this vault, decrypted, with unpushed local changes laid over them.
/// </summary>
/// <remarks>
/// <para>
/// Another facade over the same generic repository, and like the ones before it, it needed no new sync logic
/// at all.
/// </para>
/// <para>
/// <b>Deleting a tag does not touch the hosts wearing it</b>, for the reason
/// <see cref="HostGroupRepository"/> gives about groups and one more besides. The shared reason: one user
/// action would become N host writes, N outbox rows and N chances to merge against an edit nobody made, and
/// the tag's own tombstone can still lose a merge — by which time the membership it was clearing is gone.
/// The extra one: a host can wear several tags, so unpicking one from N hosts is N read-modify-writes of a
/// set rather than N clears of a pointer, and any of them that loses a merge leaves the vault holding a tag
/// that was deleted and is still worn. Hosts left holding a dangling id simply do not show that chip. See
/// <see cref="HostSecret.TagIds"/>.
/// </para>
/// </remarks>
public sealed class TagRepository(
    ItemStore items,
    OutboxStore outbox,
    VaultKeyring keyring,
    IActivityLogSink? activity = null)
{
    private readonly VaultItemRepository<TagSecret> tags =
        new(TagKind.Instance, items, outbox, keyring, activity);

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

    /// <inheritdoc cref="VaultItemRepository{TSecret}.CreateAsync" />
    public Task<Guid> CreateAsync(
        Guid vaultId,
        TagSecret tag,
        CancellationToken cancellationToken) =>
        tags.CreateAsync(vaultId, tag, cancellationToken);

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

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