CREATE TABLE IF NOT EXISTS gateway_security_event_receipts (
  issuer text NOT NULL,
  jti uuid NOT NULL,
  audience text NOT NULL,
  event_type text NOT NULL,
  transaction_id text,
  tenant_id text,
  subject_hash text,
  event_timestamp timestamptz,
  received_at timestamptz NOT NULL DEFAULT now(),
  processed_at timestamptz NOT NULL DEFAULT now(),
  PRIMARY KEY (issuer, jti)
);

CREATE INDEX IF NOT EXISTS idx_gateway_security_event_receipts_received
  ON gateway_security_event_receipts(received_at DESC);

CREATE TABLE IF NOT EXISTS gateway_oidc_revocation_watermarks (
  issuer text NOT NULL,
  tenant_id text NOT NULL,
  subject text NOT NULL,
  revoked_at timestamptz NOT NULL,
  source_jti uuid NOT NULL,
  updated_at timestamptz NOT NULL DEFAULT now(),
  PRIMARY KEY (issuer, tenant_id, subject)
);

CREATE INDEX IF NOT EXISTS idx_gateway_oidc_revocation_watermarks_lookup
  ON gateway_oidc_revocation_watermarks(issuer, tenant_id, subject, revoked_at);

CREATE TABLE IF NOT EXISTS gateway_security_event_stream_state (
  issuer text NOT NULL,
  audience text NOT NULL,
  stream_id uuid NOT NULL,
  stream_status text NOT NULL DEFAULT 'unknown',
  mode text NOT NULL DEFAULT 'bootstrap',
  last_verification_at timestamptz,
  bootstrap_until timestamptz,
  consecutive_verifications integer NOT NULL DEFAULT 0,
  pending_state_hash bytea,
  pending_state_created_at timestamptz,
  fallback_since timestamptz,
  last_error_category text,
  created_at timestamptz NOT NULL DEFAULT now(),
  updated_at timestamptz NOT NULL DEFAULT now(),
  PRIMARY KEY (issuer, audience),
  UNIQUE (stream_id),
  CONSTRAINT gateway_security_event_stream_state_mode
    CHECK (mode IN ('bootstrap','push_healthy','introspection_fallback')),
  CONSTRAINT gateway_security_event_stream_state_status
    CHECK (stream_status IN ('unknown','enabled','paused','disabled')),
  CONSTRAINT gateway_security_event_stream_state_pending_hash
    CHECK (pending_state_hash IS NULL OR octet_length(pending_state_hash) = 32)
);

CREATE TABLE IF NOT EXISTS gateway_security_event_verification_challenges (
  issuer text NOT NULL,
  audience text NOT NULL,
  state_hash bytea NOT NULL,
  created_at timestamptz NOT NULL,
  expires_at timestamptz NOT NULL,
  PRIMARY KEY (issuer, audience, state_hash),
  FOREIGN KEY (issuer, audience)
    REFERENCES gateway_security_event_stream_state(issuer, audience) ON DELETE CASCADE,
  CONSTRAINT gateway_security_event_verification_challenge_hash
    CHECK (octet_length(state_hash) = 32)
);

CREATE INDEX IF NOT EXISTS idx_gateway_security_event_challenges_expiry
  ON gateway_security_event_verification_challenges(expires_at);
