namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Transport;

public sealed class BundleSession
{
    /// <summary>
    /// Legacy per-session lockout threshold (kept on this type for the
    /// shim <see cref="Locked"/> getter). The authoritative, server-side per-bundle
    /// counter is bounded by <c>TransportOptions.MaxUnlockAttemptsPerSession</c>
    /// (default also <c>3</c>) and is what <c>BundleImporter.LoadAsync</c> consults.
    /// This constant exists so the comparison in <see cref="Locked"/> uses a named
    /// symbol that a security review can grep for, rather than a literal <c>3</c>.
    /// </summary>
    public const int MaxUnlockAttempts = 3;

    /// <summary>Unique identifier for this import session.</summary>
    public Guid SessionId { get; init; }
    /// <summary>Parsed manifest from the uploaded bundle.</summary>
    public BundleManifest Manifest { get; init; } = null!;
    /// <summary>Decrypted bundle content bytes; empty until the bundle is successfully unlocked.</summary>
    public byte[] DecryptedContent { get; init; } = Array.Empty<byte>();
    /// <summary>UTC timestamp after which this session is considered expired and must be re-uploaded.</summary>
    public DateTimeOffset ExpiresAt { get; init; }
    /// <summary>
    /// T-003: legacy per-session unlock-attempt counter. The unlock lockout is now
    /// owned by <c>IBundleSessionStore</c> and keyed by <c>BundleManifest.ContentHash</c>
    /// so retries from a second tab / CLI caller share the counter. A successful
    /// <c>LoadAsync</c> never increments this — it stays 0 on every opened session,
    /// and <see cref="Locked"/> is unreachable on a session returned by the store.
    /// Retained as a compatibility shim for callers/tests that still set it directly.
    /// </summary>
    public int FailedUnlockAttempts { get; set; }
    /// <summary>
    /// T-003 legacy: always <c>false</c> on a session returned by <c>LoadAsync</c>
    /// because lockout enforcement moved server-side; see <see cref="FailedUnlockAttempts"/>.
    /// The threshold is the named <see cref="MaxUnlockAttempts"/> constant (default 3).
    /// </summary>
    public bool Locked => FailedUnlockAttempts >= MaxUnlockAttempts;
}
