CREATE TABLE firewall_client (
    id              TEXT PRIMARY KEY,
    tenant_id       TEXT NOT NULL REFERENCES tenant (id) ON DELETE CASCADE,
    name            TEXT NOT NULL,
    hostname        TEXT,
    token_prefix    TEXT NOT NULL,
    token_hash      BLOB NOT NULL,
    status          TEXT NOT NULL DEFAULT 'pending',
    enroll_seed_used INTEGER NOT NULL DEFAULT 1,
    last_seen_at    TEXT,
    last_seen_at_source TEXT,
    last_seen_ip    TEXT,
    last_apply_at   TEXT,
    last_apply_status TEXT,
    last_apply_error TEXT,
    last_apply_prefix_count INTEGER DEFAULT 0,
    last_apply_ip_count INTEGER DEFAULT 0,
    last_apply_source TEXT,
    client_version  TEXT,
    settings_json   TEXT NOT NULL DEFAULT '{}',
    created_at      TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    approved_at     TEXT,
    approved_by_api_key_id TEXT,
    revoked_at      TEXT,
    CHECK (status IN ('pending', 'approved', 'revoked')),
    CHECK (length(trim(name)) > 0),
    CHECK (length(token_hash) = 32)
);

CREATE UNIQUE INDEX idx_firewall_client_token_hash ON firewall_client (token_hash);
CREATE INDEX idx_firewall_client_tenant_status ON firewall_client (tenant_id, status);
CREATE INDEX idx_firewall_client_last_seen ON firewall_client (last_seen_at DESC) WHERE status = 'approved';

CREATE TABLE firewall_rule (
    id            TEXT PRIMARY KEY,
    tenant_id     TEXT NOT NULL REFERENCES tenant (id) ON DELETE CASCADE,
    client_id     TEXT REFERENCES firewall_client (id) ON DELETE CASCADE,
    priority      INTEGER NOT NULL,
    action        TEXT NOT NULL,
    community_id  TEXT REFERENCES bgp_community (id) ON DELETE CASCADE,
    comment       TEXT,
    created_at    TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    updated_at    TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
    CHECK (action IN ('block', 'accept')),
    CHECK (priority >= 1 AND priority <= 10000),
    UNIQUE (tenant_id, client_id, priority)
);

CREATE INDEX idx_firewall_rule_tenant_priority ON firewall_rule (tenant_id, priority);
CREATE INDEX idx_firewall_rule_client ON firewall_rule (client_id) WHERE client_id IS NOT NULL;
CREATE INDEX idx_firewall_rule_tenant_default ON firewall_rule (tenant_id, priority) WHERE client_id IS NULL;
