import { ValidationError } from '@shade/core';

/**
 * Inbox quota policy. The relay limits per-address and per-sender storage
 * so a single ondsinnet sender can't exhaust capacity.
 */
export interface InboxQuotaConfig {
  /** Hard cap on the body size of a single PUT (bytes). Default: 1 MiB. */
  maxBlobBytes: number;
  /**
   * Hard cap on the number of non-expired blobs queued for a single
   * recipient address. PUTs past this cap return SHADE_VALIDATION.
   * Default: 1000.
   */
  maxBlobsPerAddress: number;
  /** Default TTL when sender omits ttlSeconds. Default: 7 days. */
  defaultTtlSeconds: number;
  /** Maximum TTL the relay will accept. Default: 30 days. */
  maxTtlSeconds: number;
  /** Minimum TTL. Default: 60 seconds. */
  minTtlSeconds: number;
  /** Maximum number of blobs returned in one GET. Default: 100. */
  fetchPageLimit: number;
}

export const DEFAULT_INBOX_QUOTA: InboxQuotaConfig = {
  maxBlobBytes: 1 * 1024 * 1024,
  maxBlobsPerAddress: 1000,
  defaultTtlSeconds: 7 * 24 * 60 * 60,
  maxTtlSeconds: 30 * 24 * 60 * 60,
  minTtlSeconds: 60,
  fetchPageLimit: 100,
};

export function clampTtl(ttl: number | undefined, q: InboxQuotaConfig): number {
  const v = ttl ?? q.defaultTtlSeconds;
  if (!Number.isFinite(v) || v <= 0) {
    throw new ValidationError('ttlSeconds must be positive', 'ttlSeconds');
  }
  if (v < q.minTtlSeconds) {
    throw new ValidationError(`ttlSeconds < min (${q.minTtlSeconds})`, 'ttlSeconds');
  }
  if (v > q.maxTtlSeconds) {
    throw new ValidationError(`ttlSeconds > max (${q.maxTtlSeconds})`, 'ttlSeconds');
  }
  return Math.floor(v);
}
