-- +goose Up

-- teams
CREATE TABLE teams (
    id         UUID PRIMARY KEY,
    name       TEXT NOT NULL,
    slug       TEXT NOT NULL UNIQUE,
    is_byoc    BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at TIMESTAMPTZ
);
CREATE INDEX idx_teams_slug ON teams(slug);

-- users
CREATE TABLE users (
    id            UUID PRIMARY KEY,
    email         TEXT NOT NULL UNIQUE,
    password_hash TEXT,
    name          TEXT NOT NULL DEFAULT '',
    is_admin      BOOLEAN NOT NULL DEFAULT FALSE,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at    TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- users_teams (junction)
CREATE TABLE users_teams (
    user_id    UUID NOT NULL REFERENCES users(id),
    team_id    UUID NOT NULL REFERENCES teams(id),
    is_default BOOLEAN NOT NULL DEFAULT FALSE,
    role       TEXT NOT NULL DEFAULT 'member',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (team_id, user_id)
);
CREATE INDEX idx_users_teams_user ON users_teams(user_id);

-- team_api_keys
CREATE TABLE team_api_keys (
    id         UUID PRIMARY KEY,
    team_id    UUID NOT NULL REFERENCES teams(id),
    name       TEXT NOT NULL,
    key_hash   TEXT NOT NULL UNIQUE,
    key_prefix TEXT NOT NULL,
    created_by UUID NOT NULL REFERENCES users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    last_used  TIMESTAMPTZ
);
CREATE INDEX idx_team_api_keys_team ON team_api_keys(team_id);

-- oauth_providers
CREATE TABLE oauth_providers (
    provider    TEXT NOT NULL,
    provider_id TEXT NOT NULL,
    user_id     UUID NOT NULL REFERENCES users(id),
    email       TEXT NOT NULL DEFAULT '',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (provider, provider_id)
);
CREATE INDEX idx_oauth_providers_user ON oauth_providers(user_id);

-- admin_permissions
CREATE TABLE admin_permissions (
    id         UUID PRIMARY KEY,
    user_id    UUID NOT NULL REFERENCES users(id),
    permission TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (user_id, permission)
);
CREATE INDEX idx_admin_permissions_user ON admin_permissions(user_id);

-- hosts
CREATE TABLE hosts (
    id                UUID PRIMARY KEY,
    type              TEXT NOT NULL DEFAULT 'regular',
    team_id           UUID REFERENCES teams(id),
    provider          TEXT NOT NULL DEFAULT '',
    availability_zone TEXT NOT NULL DEFAULT '',
    arch              TEXT NOT NULL DEFAULT '',
    cpu_cores         INTEGER NOT NULL DEFAULT 0,
    memory_mb         INTEGER NOT NULL DEFAULT 0,
    disk_gb           INTEGER NOT NULL DEFAULT 0,
    address           TEXT NOT NULL DEFAULT '',
    status            TEXT NOT NULL DEFAULT 'pending',
    last_heartbeat_at TIMESTAMPTZ,
    metadata          JSONB NOT NULL DEFAULT '{}',
    created_by        UUID NOT NULL REFERENCES users(id),
    created_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    cert_fingerprint  TEXT NOT NULL DEFAULT '',
    mtls_enabled      BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE INDEX idx_hosts_type ON hosts(type);
CREATE INDEX idx_hosts_team ON hosts(team_id);
CREATE INDEX idx_hosts_status ON hosts(status);

-- host_tokens
CREATE TABLE host_tokens (
    id         UUID PRIMARY KEY,
    host_id    UUID NOT NULL REFERENCES hosts(id) ON DELETE CASCADE,
    created_by UUID NOT NULL REFERENCES users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    expires_at TIMESTAMPTZ NOT NULL,
    used_at    TIMESTAMPTZ
);
CREATE INDEX idx_host_tokens_host ON host_tokens(host_id);

-- host_tags
CREATE TABLE host_tags (
    host_id UUID NOT NULL REFERENCES hosts(id) ON DELETE CASCADE,
    tag     TEXT NOT NULL,
    PRIMARY KEY (host_id, tag)
);
CREATE INDEX idx_host_tags_tag ON host_tags(tag);

-- host_refresh_tokens
CREATE TABLE host_refresh_tokens (
    id         UUID PRIMARY KEY,
    host_id    UUID NOT NULL REFERENCES hosts(id) ON DELETE CASCADE,
    token_hash TEXT NOT NULL UNIQUE,
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    revoked_at TIMESTAMPTZ
);
CREATE INDEX idx_host_refresh_tokens_host ON host_refresh_tokens(host_id);

-- templates (TEXT primary key — not UUID)
CREATE TABLE templates (
    name       TEXT PRIMARY KEY,
    type       TEXT NOT NULL DEFAULT 'base',
    vcpus      INTEGER NOT NULL DEFAULT 1,
    memory_mb  INTEGER NOT NULL DEFAULT 512,
    size_bytes BIGINT NOT NULL DEFAULT 0,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    team_id    UUID NOT NULL
);
CREATE INDEX idx_templates_team ON templates(team_id);

-- sandboxes
CREATE TABLE sandboxes (
    id             UUID PRIMARY KEY,
    team_id        UUID NOT NULL REFERENCES teams(id),
    host_id        UUID NOT NULL,
    template       TEXT NOT NULL DEFAULT 'minimal',
    status         TEXT NOT NULL DEFAULT 'pending',
    vcpus          INTEGER NOT NULL DEFAULT 1,
    memory_mb      INTEGER NOT NULL DEFAULT 512,
    timeout_sec    INTEGER NOT NULL DEFAULT 300,
    disk_size_mb   INTEGER NOT NULL DEFAULT 20480,
    guest_ip       TEXT NOT NULL DEFAULT '',
    host_ip        TEXT NOT NULL DEFAULT '',
    created_at     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    started_at     TIMESTAMPTZ,
    last_active_at TIMESTAMPTZ,
    last_updated   TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_sandboxes_status ON sandboxes(status);
CREATE INDEX idx_sandboxes_host_status ON sandboxes(host_id, status);
CREATE INDEX idx_sandboxes_team ON sandboxes(team_id);

-- audit_logs (id and team_id are UUID; actor_id and resource_id are TEXT for polymorphism)
CREATE TABLE audit_logs (
    id            UUID PRIMARY KEY,
    team_id       UUID NOT NULL,
    actor_type    TEXT NOT NULL,
    actor_id      TEXT,
    actor_name    TEXT NOT NULL DEFAULT '',
    resource_type TEXT NOT NULL,
    resource_id   TEXT,
    action        TEXT NOT NULL,
    scope         TEXT NOT NULL DEFAULT 'team',
    status        TEXT NOT NULL DEFAULT 'success',
    metadata      JSONB NOT NULL DEFAULT '{}',
    created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_audit_logs_team_time ON audit_logs(team_id, created_at DESC);
CREATE INDEX idx_audit_logs_team_resource ON audit_logs(team_id, resource_type, created_at DESC);

-- sandbox_metrics_snapshots
CREATE TABLE sandbox_metrics_snapshots (
    id                 BIGSERIAL PRIMARY KEY,
    team_id            UUID NOT NULL,
    sampled_at         TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    running_count      INTEGER NOT NULL DEFAULT 0,
    vcpus_reserved     INTEGER NOT NULL DEFAULT 0,
    memory_mb_reserved INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_metrics_snapshots_team_time ON sandbox_metrics_snapshots(team_id, sampled_at DESC);

-- sandbox_metric_points
CREATE TABLE sandbox_metric_points (
    sandbox_id UUID NOT NULL,
    tier       TEXT NOT NULL CHECK (tier IN ('10m', '2h', '24h')),
    ts         BIGINT NOT NULL,
    cpu_pct    FLOAT8 NOT NULL DEFAULT 0,
    mem_bytes  BIGINT NOT NULL DEFAULT 0,
    disk_bytes BIGINT NOT NULL DEFAULT 0,
    PRIMARY KEY (sandbox_id, tier, ts)
);
CREATE INDEX idx_sandbox_metric_points_sandbox_tier ON sandbox_metric_points(sandbox_id, tier);

-- template_builds
CREATE TABLE template_builds (
    id            UUID PRIMARY KEY,
    name          TEXT NOT NULL,
    base_template TEXT NOT NULL,
    recipe        JSONB NOT NULL DEFAULT '[]',
    healthcheck   TEXT NOT NULL DEFAULT '',
    vcpus         INTEGER NOT NULL DEFAULT 1,
    memory_mb     INTEGER NOT NULL DEFAULT 512,
    status        TEXT NOT NULL DEFAULT 'pending',
    current_step  INTEGER NOT NULL DEFAULT 0,
    total_steps   INTEGER NOT NULL DEFAULT 0,
    logs          JSONB NOT NULL DEFAULT '[]',
    error         TEXT NOT NULL DEFAULT '',
    sandbox_id    UUID,
    host_id       UUID,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    started_at    TIMESTAMPTZ,
    completed_at  TIMESTAMPTZ
);

-- +goose Down
DROP TABLE IF EXISTS template_builds;
DROP TABLE IF EXISTS sandbox_metric_points;
DROP TABLE IF EXISTS sandbox_metrics_snapshots;
DROP TABLE IF EXISTS audit_logs;
DROP TABLE IF EXISTS sandboxes;
DROP TABLE IF EXISTS templates;
DROP TABLE IF EXISTS host_refresh_tokens;
DROP TABLE IF EXISTS host_tags;
DROP TABLE IF EXISTS host_tokens;
DROP TABLE IF EXISTS hosts;
DROP TABLE IF EXISTS admin_permissions;
DROP TABLE IF EXISTS oauth_providers;
DROP TABLE IF EXISTS team_api_keys;
DROP TABLE IF EXISTS users_teams;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS teams;
