CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TYPE ioc_type AS ENUM (
    'FILENAME', 'MD5', 'REGISTRY_KEY', 'DIRECTORY', 'SERVICE_NAME', 'IP', 'FILE_PATH'
);

CREATE TYPE ioc_source AS ENUM ('FBI_FLASH', 'FS_ISAC', 'MANUAL');

CREATE TYPE confidence_level AS ENUM ('HIGH', 'MEDIUM', 'LOW');

CREATE TABLE threat_ioc (
    id          BIGSERIAL PRIMARY KEY,
    ioc_type    ioc_type NOT NULL,
    value       TEXT NOT NULL,
    description TEXT,
    source      ioc_source NOT NULL DEFAULT 'FBI_FLASH',
    source_ref  VARCHAR(100),
    confidence  confidence_level NOT NULL DEFAULT 'HIGH',
    added_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    expires_at  TIMESTAMPTZ,
    active      BOOLEAN NOT NULL DEFAULT TRUE,
    UNIQUE (ioc_type, value)
);

CREATE INDEX idx_threat_ioc_active ON threat_ioc(active);
CREATE INDEX idx_threat_ioc_type   ON threat_ioc(ioc_type);

CREATE TYPE threat_severity AS ENUM ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO');

CREATE TYPE threat_event_type AS ENUM ('PHYSICAL', 'OS_EVENT', 'FILE_SYSTEM', 'COMPOSITE');

CREATE TYPE attack_phase AS ENUM (
    'PHYSICAL_ACCESS', 'MALWARE_STAGING', 'MALWARE_EXECUTION', 'PERSISTENCE', 'CLEANUP'
);

CREATE TABLE threat_event (
    id              BIGSERIAL PRIMARY KEY,
    device_id       BIGINT,
    device_agent_id VARCHAR(100),
    event_type      threat_event_type NOT NULL,
    signal_key      VARCHAR(100) NOT NULL,
    raw_payload     JSONB,
    matched_ioc_id  BIGINT REFERENCES threat_ioc(id),
    severity        threat_severity NOT NULL,
    detected_at     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    attack_phase    attack_phase,
    sequence_id     UUID,
    institution_key VARCHAR(100),
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_threat_event_device_id  ON threat_event(device_id);
CREATE INDEX idx_threat_event_sequence   ON threat_event(sequence_id);
CREATE INDEX idx_threat_event_detected   ON threat_event(detected_at DESC);
CREATE INDEX idx_threat_event_severity   ON threat_event(severity);
CREATE INDEX idx_threat_event_agent      ON threat_event(device_agent_id);

CREATE TYPE sequence_type AS ENUM ('JACKPOTTING', 'SKIMMING', 'UNKNOWN');

CREATE TYPE auto_response_action AS ENUM ('NONE', 'SHUTDOWN', 'NOTIFICATION', 'LOCKDOWN');

CREATE TABLE precursor_sequence_alert (
    id                  BIGSERIAL PRIMARY KEY,
    device_id           BIGINT,
    device_agent_id     VARCHAR(100),
    sequence_type       sequence_type NOT NULL DEFAULT 'JACKPOTTING',
    phases_detected     attack_phase[] NOT NULL DEFAULT '{}',
    confidence          NUMERIC(4,3) NOT NULL DEFAULT 0.0,
    triggered_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    auto_response_taken auto_response_action NOT NULL DEFAULT 'NONE',
    resolved_at         TIMESTAMPTZ,
    resolved_by         VARCHAR(200),
    institution_key     VARCHAR(100),
    sequence_id         UUID NOT NULL DEFAULT uuid_generate_v4()
);

CREATE INDEX idx_sequence_alert_device  ON precursor_sequence_alert(device_id);
CREATE INDEX idx_sequence_alert_trigger ON precursor_sequence_alert(triggered_at DESC);
CREATE INDEX idx_sequence_alert_open    ON precursor_sequence_alert(resolved_at) WHERE resolved_at IS NULL;

CREATE TYPE os_eol_status AS ENUM ('SUPPORTED', 'EOL', 'UNKNOWN');

CREATE TABLE device_security_posture (
    device_id                  BIGINT PRIMARY KEY,
    device_agent_id            VARCHAR(100),
    institution_key            VARCHAR(100),
    audit_policy_compliant     BOOLEAN,
    gold_image_validated_at    TIMESTAMPTZ,
    gold_image_hash            VARCHAR(128),
    current_image_hash         VARCHAR(128),
    disk_encryption_enabled    BOOLEAN,
    os_version                 VARCHAR(200),
    os_eol_status              os_eol_status NOT NULL DEFAULT 'UNKNOWN',
    software_whitelist_enabled BOOLEAN,
    last_posture_check_at      TIMESTAMPTZ,
    posture_score              INTEGER,
    updated_at                 TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
