-- -----------------------------------------------------------------------------
-- Migration: 20260129_001_create_identity_watchlist
-- Sprint: SPRINT_0129_001_ATTESTOR_identity_watchlist_alerting
-- Task: WATCH-004
-- Description: Creates identity watchlist and alert deduplication tables.
-- -----------------------------------------------------------------------------

-- Watchlist entries table
CREATE TABLE IF NOT EXISTS attestor.identity_watchlist (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id TEXT NOT NULL,
    scope TEXT NOT NULL DEFAULT 'Tenant',
    display_name TEXT NOT NULL,
    description TEXT,

    -- Identity matching fields (at least one required)
    issuer TEXT,
    subject_alternative_name TEXT,
    key_id TEXT,
    match_mode TEXT NOT NULL DEFAULT 'Exact',

    -- Alert configuration
    severity TEXT NOT NULL DEFAULT 'Warning',
    enabled BOOLEAN NOT NULL DEFAULT TRUE,
    channel_overrides JSONB,
    suppress_duplicates_minutes INT NOT NULL DEFAULT 60,

    -- Metadata
    tags TEXT[],
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by TEXT NOT NULL,
    updated_by TEXT NOT NULL,

    -- Constraints
    CONSTRAINT chk_at_least_one_identity CHECK (
        issuer IS NOT NULL OR
        subject_alternative_name IS NOT NULL OR
        key_id IS NOT NULL
    ),
    CONSTRAINT chk_scope_valid CHECK (scope IN ('Tenant', 'Global', 'System')),
    CONSTRAINT chk_match_mode_valid CHECK (match_mode IN ('Exact', 'Prefix', 'Glob', 'Regex')),
    CONSTRAINT chk_severity_valid CHECK (severity IN ('Info', 'Warning', 'Critical')),
    CONSTRAINT chk_suppress_duplicates_positive CHECK (suppress_duplicates_minutes >= 1)
);

-- Performance indexes for active entry lookup
CREATE INDEX IF NOT EXISTS idx_watchlist_tenant_enabled
    ON attestor.identity_watchlist(tenant_id)
    WHERE enabled = TRUE;

CREATE INDEX IF NOT EXISTS idx_watchlist_scope_enabled
    ON attestor.identity_watchlist(scope)
    WHERE enabled = TRUE;

CREATE INDEX IF NOT EXISTS idx_watchlist_issuer
    ON attestor.identity_watchlist(issuer)
    WHERE enabled = TRUE AND issuer IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_watchlist_san
    ON attestor.identity_watchlist(subject_alternative_name)
    WHERE enabled = TRUE AND subject_alternative_name IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_watchlist_keyid
    ON attestor.identity_watchlist(key_id)
    WHERE enabled = TRUE AND key_id IS NOT NULL;

-- Alert deduplication table
CREATE TABLE IF NOT EXISTS attestor.identity_alert_dedup (
    watchlist_id UUID NOT NULL,
    identity_hash TEXT NOT NULL,
    last_alert_at TIMESTAMPTZ NOT NULL,
    alert_count INT NOT NULL DEFAULT 0,
    PRIMARY KEY (watchlist_id, identity_hash)
);

-- Index for cleanup
CREATE INDEX IF NOT EXISTS idx_alert_dedup_last_alert
    ON attestor.identity_alert_dedup(last_alert_at);

-- Comment documentation
COMMENT ON TABLE attestor.identity_watchlist IS
    'Watchlist entries for monitoring signing identity appearances in transparency logs.';

COMMENT ON COLUMN attestor.identity_watchlist.scope IS
    'Visibility scope: Tenant (owning tenant only), Global (all tenants), System (read-only).';

COMMENT ON COLUMN attestor.identity_watchlist.match_mode IS
    'Pattern matching mode: Exact, Prefix, Glob, or Regex.';

COMMENT ON COLUMN attestor.identity_watchlist.suppress_duplicates_minutes IS
    'Deduplication window in minutes. Alerts for same identity within window are suppressed.';

COMMENT ON TABLE attestor.identity_alert_dedup IS
    'Tracks alert deduplication state to prevent alert storms.';
