namespace NATS.Server.Configuration;

// Maps to Go's JetStreamConfig struct in server/opts.go and server/jetstream.go.
// Controls the lifecycle parameters for the JetStream subsystem.
public sealed class JetStreamOptions
{
    // Go: server/jetstream.go constants (dynJetStreamConfig defaults)
    public const string JetStreamStoreDir = "jetstream";
    public const long JetStreamMaxStoreDefault = 1L << 40; // 1 TiB
    public const long JetStreamMaxMemDefault = 256L * 1024 * 1024; // 256 MiB

    /// <summary>
    /// Directory where JetStream persists stream data.
    /// Maps to Go's JetStreamConfig.StoreDir (jetstream.go:enableJetStream:430).
    /// An empty string disables file-backed persistence (memory-only mode).
    /// </summary>
    public string StoreDir { get; set; } = string.Empty;

    /// <summary>
    /// Maximum bytes of memory storage across all streams. 0 means unlimited.
    /// Maps to Go's JetStreamConfig.MaxMemory (jetstream.go:enableJetStream:471).
    /// </summary>
    public long MaxMemoryStore { get; set; }

    /// <summary>
    /// Maximum bytes of file storage across all streams. 0 means unlimited.
    /// Maps to Go's JetStreamConfig.MaxStore (jetstream.go:enableJetStream:472).
    /// </summary>
    public long MaxFileStore { get; set; }

    /// <summary>
    /// Maximum number of streams allowed. 0 means unlimited.
    /// Maps to Go's JetStreamAccountLimits.MaxStreams (jetstream.go).
    /// </summary>
    public int MaxStreams { get; set; }

    /// <summary>
    /// Maximum number of consumers allowed across all streams. 0 means unlimited.
    /// Maps to Go's JetStreamAccountLimits.MaxConsumers (jetstream.go).
    /// </summary>
    public int MaxConsumers { get; set; }

    /// <summary>
    /// JetStream domain name for this server. Used for domain-scoped routing and
    /// subject prefix isolation in clustered deployments.
    /// Maps to Go's Options.JetStreamDomain (opts.go).
    /// </summary>
    public string? Domain { get; set; }

    /// <summary>
    /// File-store sync interval.
    /// Go reference: server/jetstream.go JetStreamConfig.SyncInterval.
    /// </summary>
    public TimeSpan SyncInterval { get; set; }

    /// <summary>
    /// Forces sync on each write when true.
    /// Go reference: server/jetstream.go JetStreamConfig.SyncAlways.
    /// </summary>
    public bool SyncAlways { get; set; }

    /// <summary>
    /// Whether compression is allowed for JetStream replication/storage paths.
    /// Go reference: server/jetstream.go JetStreamConfig.CompressOK.
    /// </summary>
    public bool CompressOk { get; set; }

    /// <summary>
    /// Unique placement tag used in clustered deployments.
    /// Go reference: server/jetstream.go JetStreamConfig.UniqueTag.
    /// </summary>
    public string? UniqueTag { get; set; }

    /// <summary>
    /// Enables strict validation mode for JetStream.
    /// Go reference: server/jetstream.go JetStreamConfig.Strict.
    /// </summary>
    public bool Strict { get; set; }

    /// <summary>
    /// Account-level maximum pending acknowledgements.
    /// Go reference: server/jetstream.go JetStreamAccountLimits.MaxAckPending.
    /// </summary>
    public int MaxAckPending { get; set; }

    /// <summary>
    /// Maximum bytes allowed per memory-backed stream.
    /// Go reference: server/jetstream.go JetStreamAccountLimits.MemoryMaxStreamBytes.
    /// </summary>
    public long MemoryMaxStreamBytes { get; set; }

    /// <summary>
    /// Maximum bytes allowed per file-backed stream.
    /// Go reference: server/jetstream.go JetStreamAccountLimits.StoreMaxStreamBytes.
    /// </summary>
    public long StoreMaxStreamBytes { get; set; }

    /// <summary>
    /// When true, stream configs must specify explicit MaxBytes.
    /// Go reference: server/jetstream.go JetStreamAccountLimits.MaxBytesRequired.
    /// </summary>
    public bool MaxBytesRequired { get; set; }

    /// <summary>
    /// Optional per-tier JetStream limits keyed by tier name.
    /// Go reference: server/jetstream.go JetStreamAccountLimits tiers.
    /// </summary>
    public Dictionary<string, NATS.Server.JetStream.JetStreamTier> Tiers { get; set; } = new(StringComparer.Ordinal);
}
