-- OCDP Multi-Tenant Migration Script
-- Adds multi-tenant fields and new tables for workspace isolation

-- ===== Phase 1: Add new columns to existing tables =====

-- Add multi-tenant fields to users table
ALTER TABLE users ADD COLUMN IF NOT EXISTS role VARCHAR(20) NOT NULL DEFAULT 'user';
ALTER TABLE users ADD COLUMN IF NOT EXISTS workspace_id VARCHAR(36);
ALTER TABLE users ADD COLUMN IF NOT EXISTS is_active BOOLEAN NOT NULL DEFAULT TRUE;
ALTER TABLE users ADD COLUMN IF NOT EXISTS must_change_password BOOLEAN NOT NULL DEFAULT FALSE;

-- Add indexes for new user fields
CREATE INDEX IF NOT EXISTS idx_users_role ON users(role);
CREATE INDEX IF NOT EXISTS idx_users_workspace_id ON users(workspace_id);
CREATE INDEX IF NOT EXISTS idx_users_is_active ON users(is_active);

-- Add multi-tenant fields to clusters table
ALTER TABLE clusters ADD COLUMN IF NOT EXISTS workspace_id VARCHAR(36);
ALTER TABLE clusters ADD COLUMN IF NOT EXISTS owner_id VARCHAR(36);
ALTER TABLE clusters ADD COLUMN IF NOT EXISTS isolation_mode VARCHAR(20) NOT NULL DEFAULT 'namespace';
ALTER TABLE clusters ADD COLUMN IF NOT EXISTS default_namespace VARCHAR(255);
ALTER TABLE clusters ADD COLUMN IF NOT EXISTS is_shared BOOLEAN NOT NULL DEFAULT FALSE;

-- Add index for cluster workspace
CREATE INDEX IF NOT EXISTS idx_clusters_workspace_id ON clusters(workspace_id);

-- Add multi-tenant fields to registries table
ALTER TABLE registries ADD COLUMN IF NOT EXISTS workspace_id VARCHAR(36);
ALTER TABLE registries ADD COLUMN IF NOT EXISTS owner_id VARCHAR(36);
ALTER TABLE registries ADD COLUMN IF NOT EXISTS is_shared BOOLEAN NOT NULL DEFAULT FALSE;

-- Add index for registry workspace
CREATE INDEX IF NOT EXISTS idx_registries_workspace_id ON registries(workspace_id);

-- Add multi-tenant fields to instances table
ALTER TABLE instances ADD COLUMN IF NOT EXISTS workspace_id VARCHAR(36);
ALTER TABLE instances ADD COLUMN IF NOT EXISTS owner_id VARCHAR(36);
ALTER TABLE instances ADD COLUMN IF NOT EXISTS values_template_id VARCHAR(36);
ALTER TABLE instances ADD COLUMN IF NOT EXISTS user_override_yaml TEXT;
ALTER TABLE instances ADD COLUMN IF NOT EXISTS cpu_requested DECIMAL(10,2) NOT NULL DEFAULT 0;
ALTER TABLE instances ADD COLUMN IF NOT EXISTS memory_requested VARCHAR(50) NOT NULL DEFAULT '0Mi';
ALTER TABLE instances ADD COLUMN IF NOT EXISTS gpu_requested DECIMAL(10,2) NOT NULL DEFAULT 0;
ALTER TABLE instances ADD COLUMN IF NOT EXISTS gpu_memory_requested VARCHAR(50) NOT NULL DEFAULT '0Mi';

-- Add index for instance workspace
CREATE INDEX IF NOT EXISTS idx_instances_workspace_id ON instances(workspace_id);

-- ===== Phase 2: Create new tables =====

-- Create workspaces table
CREATE TABLE IF NOT EXISTS workspaces (
    id VARCHAR(36) PRIMARY KEY,
    name VARCHAR(255) NOT NULL UNIQUE,
    description TEXT,
    created_by VARCHAR(36),
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_workspaces_name ON workspaces(name);

-- Create workspace_quotas table
CREATE TABLE IF NOT EXISTS workspace_quotas (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36) NOT NULL,
    resource_type VARCHAR(50) NOT NULL,
    hard_limit DECIMAL(10,2) NOT NULL,
    soft_limit DECIMAL(10,2) NOT NULL,
    used DECIMAL(10,2) NOT NULL DEFAULT 0,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, resource_type),
    CONSTRAINT fk_workspace_quotas_workspace FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE
);

CREATE INDEX IF NOT EXISTS idx_workspace_quotas_workspace_id ON workspace_quotas(workspace_id);

-- Create storage_backends table
CREATE TABLE IF NOT EXISTS storage_backends (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    owner_id VARCHAR(36),
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL,
    config JSONB NOT NULL,
    description TEXT,
    is_default BOOLEAN NOT NULL DEFAULT FALSE,
    is_shared BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, name)
);

CREATE INDEX IF NOT EXISTS idx_storage_backends_workspace_id ON storage_backends(workspace_id);

-- Create chart_references table
CREATE TABLE IF NOT EXISTS chart_references (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    registry_id VARCHAR(36),
    repository VARCHAR(500) NOT NULL,
    chart_name VARCHAR(255) NOT NULL,
    description TEXT,
    is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, registry_id, repository)
);

CREATE INDEX IF NOT EXISTS idx_chart_references_workspace_id ON chart_references(workspace_id);
CREATE INDEX IF NOT EXISTS idx_chart_references_registry_id ON chart_references(registry_id);

-- Create values_templates table
CREATE TABLE IF NOT EXISTS values_templates (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    owner_id VARCHAR(36),
    chart_reference_id VARCHAR(36),
    name VARCHAR(255) NOT NULL,
    description TEXT,
    values_yaml TEXT NOT NULL,
    version INTEGER NOT NULL DEFAULT 1,
    is_default BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(workspace_id, chart_reference_id, name)
);

CREATE INDEX IF NOT EXISTS idx_values_templates_workspace_id ON values_templates(workspace_id);
CREATE INDEX IF NOT EXISTS idx_values_templates_chart_reference_id ON values_templates(chart_reference_id);

-- Create user_config_overrides table
CREATE TABLE IF NOT EXISTS user_config_overrides (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    user_id VARCHAR(36),
    target_type VARCHAR(50) NOT NULL,
    target_id VARCHAR(36),
    config JSONB NOT NULL,
    priority INTEGER NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_user_config_overrides_workspace_id ON user_config_overrides(workspace_id);
CREATE INDEX IF NOT EXISTS idx_user_config_overrides_user_id ON user_config_overrides(user_id);

-- Create audit_logs table
CREATE TABLE IF NOT EXISTS audit_logs (
    id VARCHAR(36) PRIMARY KEY,
    workspace_id VARCHAR(36),
    user_id VARCHAR(36),
    action VARCHAR(100) NOT NULL,
    resource_type VARCHAR(50) NOT NULL,
    resource_id VARCHAR(36),
    resource_name VARCHAR(255),
    details JSONB,
    ip_address VARCHAR(50),
    user_agent TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_audit_logs_workspace_id ON audit_logs(workspace_id);
CREATE INDEX IF NOT EXISTS idx_audit_logs_user_id ON audit_logs(user_id);
CREATE INDEX IF NOT EXISTS idx_audit_logs_created_at ON audit_logs(created_at);

-- ===== Phase 3: Create admin user =====
-- Note: Default password is 'admin123' (bcrypt hash will be set by application)
-- The admin user will have NULL workspace_id to indicate global access

INSERT INTO users (id, username, password_hash, email, role, workspace_id, is_active, must_change_password)
VALUES (
    '00000000-0000-0000-0000-000000000001',
    'admin',
    '$2a$10$placeholder',  -- Replace with actual bcrypt hash in production
    'admin@ocdp.local',
    'admin',
    NULL,
    TRUE,
    TRUE
) ON CONFLICT (username) DO NOTHING;

-- Update schema version
INSERT INTO schema_migrations (version) VALUES ('v2.0.0-multi-tenant')
ON CONFLICT (version) DO NOTHING;

-- Grant permissions (adjust as needed for your setup)
-- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ocdp_user;
-- GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ocdp_user;