-- 011_opnfwd.sql — wire panel into opnfwd's port-forward HTTP API.
--
-- Three changes:
-- 1. agents.lan_ip — operator-set LAN IP for this agent. opnfwd's `target`
--    field needs the LAN-side IP of the host running the game container.
--    Defaulted blank; the dashboard's agent edit modal lets the operator
--    fill it in. Without it, the opnfwd integration silently no-ops for
--    instances on that agent (loud log line, no destructive failure).
--
-- 2. panel_settings — singleton key/value table for instance-wide knobs.
--    Today: opnfwd_enabled / opnfwd_url / opnfwd_token. Future: anything
--    else that's "global, operator-edited, doesn't fit elsewhere."
--
-- 3. instance_forwards — what the panel believes it owns in opnfwd. We
--    persist the {nat_uuid, filter_uuid} returned by `POST /api/forwards`
--    so we can target opnfwd's bulk-delete on instance delete. Composite
--    PK on (instance_id, port_name) — every public port gets one row.

ALTER TABLE agents ADD COLUMN IF NOT EXISTS lan_ip TEXT NOT NULL DEFAULT '';

CREATE TABLE IF NOT EXISTS panel_settings (
    key        TEXT PRIMARY KEY,
    value      TEXT NOT NULL DEFAULT '',
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

INSERT INTO panel_settings (key, value) VALUES
    ('opnfwd_enabled', 'false'),
    ('opnfwd_url',     ''),
    ('opnfwd_token',   '')
ON CONFLICT (key) DO NOTHING;

CREATE TABLE IF NOT EXISTS instance_forwards (
    instance_id TEXT NOT NULL,
    port_name   TEXT NOT NULL,
    nat_uuid    TEXT NOT NULL DEFAULT '',
    filter_uuid TEXT NOT NULL DEFAULT '',
    target_ip   TEXT NOT NULL,
    host_port   INTEGER NOT NULL,
    proto       TEXT NOT NULL,
    descr       TEXT NOT NULL DEFAULT '',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (instance_id, port_name)
);

CREATE INDEX IF NOT EXISTS instance_forwards_instance_id_idx
    ON instance_forwards(instance_id);
