-- Release module full schema bootstrap for local dev compose.
-- Includes schemas, tenants, integration hub, environments, release management,
-- workflow, promotion, deployment, agents, trust/signing, and read models.
-- All statements are idempotent (IF NOT EXISTS / ON CONFLICT).

-- Shared tenants (required by release.integrations FK)
CREATE SCHEMA IF NOT EXISTS shared;
CREATE TABLE IF NOT EXISTS shared.tenants (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id TEXT NOT NULL UNIQUE,
    name TEXT NOT NULL,
    display_name TEXT,
    is_default BOOLEAN NOT NULL DEFAULT false,
    status TEXT NOT NULL DEFAULT 'active',
    settings JSONB NOT NULL DEFAULT '{}',
    metadata JSONB NOT NULL DEFAULT '{}',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE UNIQUE INDEX IF NOT EXISTS uq_shared_tenants_single_default
    ON shared.tenants (is_default)
    WHERE is_default;

-- Seed the generic default tenant required by release/shared foreign keys.
INSERT INTO shared.tenants (tenant_id, name, display_name, is_default, status)
VALUES ('default', 'Default', 'Default Tenant', true, 'active')
ON CONFLICT (tenant_id) DO UPDATE
SET name = EXCLUDED.name,
    display_name = EXCLUDED.display_name,
    is_default = EXCLUDED.is_default,
    status = EXCLUDED.status;

-- Release schemas
CREATE SCHEMA IF NOT EXISTS release;
CREATE SCHEMA IF NOT EXISTS release_app;

-- Helper function for updated_at triggers
CREATE OR REPLACE FUNCTION release.update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = now();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Tenant isolation function
CREATE OR REPLACE FUNCTION release_app.require_current_tenant()
RETURNS UUID
LANGUAGE plpgsql STABLE SECURITY DEFINER
AS $$
DECLARE
    v_tenant TEXT;
BEGIN
    v_tenant := current_setting('app.tenant_id', true);
    IF v_tenant IS NULL OR v_tenant = '' THEN
        RAISE EXCEPTION 'app.tenant_id session variable not set';
    END IF;
    RETURN v_tenant::UUID;
END;
$$;

-- Analytics schema
CREATE SCHEMA IF NOT EXISTS analytics;

-- ── Regions (bootstrap fallback for release.regions) ──
CREATE TABLE IF NOT EXISTS release.regions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES shared.tenants(id) ON DELETE CASCADE,
    name VARCHAR(100) NOT NULL,
    display_name VARCHAR(255) NOT NULL,
    description TEXT,
    crypto_profile VARCHAR(50) NOT NULL DEFAULT 'international',
    sort_order INT NOT NULL DEFAULT 0,
    status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active','decommissioning','archived')),
    metadata JSONB NOT NULL DEFAULT '{}',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID,
    UNIQUE(tenant_id, name)
);

-- ── Infrastructure Bindings (bootstrap fallback) ──
CREATE TABLE IF NOT EXISTS release.infrastructure_bindings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES shared.tenants(id) ON DELETE CASCADE,
    integration_id UUID,
    scope_type TEXT NOT NULL CHECK (scope_type IN ('tenant','region','environment')),
    scope_id UUID,
    binding_role TEXT NOT NULL CHECK (binding_role IN ('registry','vault','settings_store')),
    priority INT NOT NULL DEFAULT 0,
    config_overrides JSONB NOT NULL DEFAULT '{}',
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by UUID
);

-- ── Topology Point Status (bootstrap fallback) ──
CREATE TABLE IF NOT EXISTS release.topology_point_status (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,
    target_id UUID,
    gate_name TEXT NOT NULL,
    status TEXT NOT NULL CHECK (status IN ('pending','pass','fail','skip')),
    message TEXT,
    details JSONB NOT NULL DEFAULT '{}',
    checked_at TIMESTAMPTZ,
    duration_ms INT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ── Pending Deletions (bootstrap fallback) ──
CREATE TABLE IF NOT EXISTS release.pending_deletions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL,
    entity_type TEXT NOT NULL CHECK (entity_type IN ('tenant','region','environment','target','agent','integration')),
    entity_id UUID NOT NULL,
    entity_name TEXT NOT NULL,
    status TEXT NOT NULL CHECK (status IN ('pending','confirmed','executing','completed','cancelled')),
    cool_off_hours INT NOT NULL,
    cool_off_expires_at TIMESTAMPTZ NOT NULL,
    cascade_summary JSONB NOT NULL DEFAULT '{}',
    reason TEXT,
    requested_by UUID NOT NULL,
    requested_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    confirmed_by UUID,
    confirmed_at TIMESTAMPTZ,
    executed_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
