CREATE TABLE firewall_client (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       UUID NOT NULL REFERENCES tenant (id) ON DELETE CASCADE,
    name            TEXT NOT NULL,
    hostname        TEXT,
    token_prefix    TEXT NOT NULL,
    token_hash      BYTEA NOT NULL,
    status          TEXT NOT NULL DEFAULT 'pending',
    enroll_seed_used BOOLEAN NOT NULL DEFAULT TRUE,
    last_seen_at    TIMESTAMPTZ,
    last_seen_at_source TEXT,
    last_seen_ip    TEXT,
    last_apply_at   TIMESTAMPTZ,
    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   JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    approved_at     TIMESTAMPTZ,
    approved_by_api_key_id UUID,
    revoked_at      TIMESTAMPTZ,
    CONSTRAINT firewall_client_status_chk CHECK (status IN ('pending', 'approved', 'revoked')),
    CONSTRAINT firewall_client_name_chk CHECK (length(trim(name)) > 0),
    CONSTRAINT firewall_client_token_hash_len_chk CHECK (octet_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            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id     UUID NOT NULL REFERENCES tenant (id) ON DELETE CASCADE,
    client_id     UUID REFERENCES firewall_client (id) ON DELETE CASCADE,
    priority      INTEGER NOT NULL,
    action        TEXT NOT NULL,
    community_id  UUID REFERENCES bgp_community (id) ON DELETE CASCADE,
    comment       TEXT,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT firewall_rule_action_chk CHECK (action IN ('block', 'accept')),
    CONSTRAINT firewall_rule_priority_chk CHECK (priority >= 1 AND priority <= 10000),
    CONSTRAINT firewall_rule_scope_uniq 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;
