-- AppGate SDP integration — Postgres schema.
--
-- Mirrors the slices of Appgate SDP Controller REST API v22.5 that Pulse
-- surfaces for the manager-on-the-go view:
--
--   • Active sessions (current snapshot)        -> appgate_active_sessions
--   • On-boarded devices (slowly changing list) -> appgate_devices
--   • Controllers / Gateways                    -> appgate_appliances
--   • Per-user license consumption              -> appgate_license_users
--   • Daily license capacity rollup             -> appgate_license_snapshots
--   • Daily login totals (history series)       -> appgate_user_logins_daily

-- Current active sessions — replaced each sync (no history beyond appliances log).
CREATE TABLE IF NOT EXISTS appgate_active_sessions (
    distinguished_name  TEXT PRIMARY KEY,
    device_id           UUID,
    username            TEXT,
    provider_name       TEXT,
    hostname            TEXT,
    os_family           TEXT,
    os_name             TEXT,
    os_parent           TEXT,
    client_version      TEXT,
    client_type         TEXT,
    client_support      TEXT,
    geo_ip_latitude     DOUBLE PRECISION,
    geo_ip_longitude    DOUBLE PRECISION,
    gateways            JSONB,
    synced_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_appgate_sessions_username ON appgate_active_sessions(username);
CREATE INDEX IF NOT EXISTS idx_appgate_sessions_provider ON appgate_active_sessions(provider_name);

-- On-boarded devices — persistent inventory.  Uses the same soft-delete
-- pattern as qbo_invoices: a full sync tombstones any row not returned.
CREATE TABLE IF NOT EXISTS appgate_devices (
    distinguished_name  TEXT PRIMARY KEY,
    device_id           UUID,
    username            TEXT,
    provider_name       TEXT,
    device_type         TEXT,
    hostname            TEXT,
    on_boarded_at       TIMESTAMPTZ,
    last_seen_at        TIMESTAMPTZ,
    synced_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    is_deleted          BOOLEAN NOT NULL DEFAULT false,
    deleted_at          TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_appgate_devices_username   ON appgate_devices(username);
CREATE INDEX IF NOT EXISTS idx_appgate_devices_is_deleted ON appgate_devices(is_deleted);
CREATE INDEX IF NOT EXISTS idx_appgate_devices_last_seen  ON appgate_devices(last_seen_at);

-- Appliances (controllers, gateways, log servers, etc.).
CREATE TABLE IF NOT EXISTS appgate_appliances (
    id                          UUID PRIMARY KEY,
    name                        TEXT NOT NULL,
    hostname                    TEXT,
    notes                       TEXT,
    version                     INTEGER,
    site                        TEXT,
    site_name                   TEXT,
    activated                   BOOLEAN,
    pending_certificate_renewal BOOLEAN,
    tags                        JSONB,
    roles                       JSONB,   -- {controller, gateway, logServer, ...} subset flags
    raw                         JSONB,   -- full payload — versioned schema changes
    created_at                  TIMESTAMPTZ,
    updated_at                  TIMESTAMPTZ,
    synced_at                   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    is_deleted                  BOOLEAN NOT NULL DEFAULT false,
    deleted_at                  TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_appgate_appliances_is_deleted ON appgate_appliances(is_deleted);
CREATE INDEX IF NOT EXISTS idx_appgate_appliances_site      ON appgate_appliances(site);

-- Per-user license consumption — current snapshot, replaced each sync.
CREATE TABLE IF NOT EXISTS appgate_license_users (
    user_distinguished_name TEXT PRIMARY KEY,
    username                TEXT,
    provider_name           TEXT,
    license_type            TEXT,
    profile_name            TEXT,
    created_at              TIMESTAMPTZ,
    last_seen_at            TIMESTAMPTZ,
    synced_at               TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_appgate_license_users_username ON appgate_license_users(username);

-- Daily license capacity rollup — one row per day, history retained.
CREATE TABLE IF NOT EXISTS appgate_license_snapshots (
    snapshot_date         DATE PRIMARY KEY,
    max_users             INTEGER,
    max_portal_users      INTEGER,
    max_service_users     INTEGER,
    used_users            INTEGER,
    expiration            TIMESTAMPTZ,
    license_type          INTEGER,
    license_version       INTEGER,
    risk_engine_enabled   BOOLEAN,
    app_discovery_enabled BOOLEAN,
    captured_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Daily login totals — derived from the rolling 24h /stats/user-logins endpoint.
-- Sync replaces yesterday/today rows; older days never change.
CREATE TABLE IF NOT EXISTS appgate_user_logins_daily (
    login_date    DATE PRIMARY KEY,
    total_logins  INTEGER NOT NULL DEFAULT 0,
    captured_at   TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Sync history.
CREATE TABLE IF NOT EXISTS appgate_sync_history (
    id              SERIAL PRIMARY KEY,
    sync_id         TEXT NOT NULL,
    sync_type       TEXT NOT NULL,
    triggered_by    TEXT NOT NULL,
    started_at      TIMESTAMPTZ NOT NULL,
    completed_at    TIMESTAMPTZ,
    status          TEXT NOT NULL,
    sessions_synced INTEGER NOT NULL DEFAULT 0,
    devices_synced  INTEGER NOT NULL DEFAULT 0,
    devices_tombstoned INTEGER NOT NULL DEFAULT 0,
    appliances_synced  INTEGER NOT NULL DEFAULT 0,
    appliances_tombstoned INTEGER NOT NULL DEFAULT 0,
    license_users_synced  INTEGER NOT NULL DEFAULT 0,
    last_error      TEXT
);

CREATE INDEX IF NOT EXISTS idx_appgate_sync_history_started ON appgate_sync_history(started_at DESC);

-- Scheduler entries — disabled by default until credentials configured.
-- sync_schedules has no unique constraint on name, so guard with NOT EXISTS.
INSERT INTO sync_schedules (id, name, description, cron_expression, sync_type, is_enabled)
SELECT 'appgate-sessions',
       'AppGate Sessions',
       'Active session snapshot every 5 minutes during business hours.',
       '*/5 11-23 * * 1-5', 'appgate-sessions', false
 WHERE NOT EXISTS (SELECT 1 FROM sync_schedules WHERE name = 'AppGate Sessions');

INSERT INTO sync_schedules (id, name, description, cron_expression, sync_type, is_enabled)
SELECT 'appgate-daily',
       'AppGate Daily',
       'Full AppGate sync — devices, appliances, license, login totals.',
       '15 6 * * *', 'appgate-daily', false
 WHERE NOT EXISTS (SELECT 1 FROM sync_schedules WHERE name = 'AppGate Daily');
