import { TABLES } from "../protocol/index.mjs";

export const CLOUD_CORE_MIGRATION_ID = "0001_cloud_core_skeleton";
export const CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION = "runtime-durable-postgres-v2";
export const CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE = "hwlab_schema_migrations";

export const FROZEN_CLOUD_CORE_TABLES = Object.freeze([...TABLES]);

export const CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE_COLUMNS = Object.freeze([
  "id",
  "schema_version",
  "applied_at",
  "migration_json"
]);

export const CLOUD_RUNTIME_DURABLE_TABLE_COLUMNS = Object.freeze({
  users: Object.freeze([
    "id",
    "username",
    "display_name",
    "role",
    "status",
    "password_hash",
    "created_at",
    "updated_at"
  ]),
  user_sessions: Object.freeze([
    "id",
    "user_id",
    "session_token_hash",
    "created_at",
    "last_seen_at",
    "expires_at",
    "revoked_at"
  ]),
  gateway_sessions: Object.freeze([
    "id",
    "project_id",
    "gateway_service_id",
    "status",
    "started_at",
    "ended_at",
    "gateway_session_json"
  ]),
  box_resources: Object.freeze([
    "id",
    "project_id",
    "gateway_session_id",
    "resource_state",
    "labels_json",
    "resource_json",
    "updated_at"
  ]),
  box_capabilities: Object.freeze([
    "id",
    "box_resource_id",
    "capability_type",
    "capability_json",
    "updated_at"
  ]),
  hardware_operations: Object.freeze([
    "id",
    "project_id",
    "requested_by",
    "operation_type",
    "operation_json",
    "status",
    "requested_at",
    "updated_at"
  ]),
  audit_events: Object.freeze([
    "id",
    "request_id",
    "actor",
    "source",
    "operation",
    "target",
    "result",
    "timestamp",
    "event_json"
  ]),
  evidence_records: Object.freeze([
    "id",
    "project_id",
    "operation_id",
    "evidence_type",
    "uri",
    "metadata_json",
    "created_at"
  ]),
  agent_sessions: Object.freeze([
    "id",
    "project_id",
    "agent_id",
    "status",
    "started_at",
    "ended_at",
    "owner_user_id",
    "conversation_id",
    "thread_id",
    "last_trace_id",
    "session_json",
    "updated_at"
  ]),
  account_workspaces: Object.freeze([
    "id",
    "owner_user_id",
    "project_id",
    "name",
    "status",
    "is_default",
    "selected_conversation_id",
    "selected_agent_session_id",
    "active_trace_id",
    "provider_profile",
    "workspace_json",
    "revision",
    "updated_by_session_id",
    "updated_by_client",
    "created_at",
    "updated_at"
  ])
});

export const CLOUD_CORE_MIGRATIONS = Object.freeze([
  {
    id: CLOUD_CORE_MIGRATION_ID,
    path: "internal/db/migrations/0001_cloud_core_skeleton.sql",
    tables: FROZEN_CLOUD_CORE_TABLES,
    connectsToDatabase: false,
    runtimeDurableAdapterSchemaVersion: CLOUD_RUNTIME_DURABLE_ADAPTER_SCHEMA_VERSION,
    runtimeDurableMigrationTable: CLOUD_RUNTIME_DURABLE_MIGRATION_TABLE
  }
]);

export function assertFrozenCloudCoreTables(tables = FROZEN_CLOUD_CORE_TABLES) {
  const missing = TABLES.filter((table) => !tables.includes(table));
  if (missing.length > 0) {
    throw new Error(`cloud core schema is missing frozen tables: ${missing.join(", ")}`);
  }
}

export function requiredRuntimeDurableColumns() {
  return Object.entries(CLOUD_RUNTIME_DURABLE_TABLE_COLUMNS).flatMap(([table, columns]) =>
    columns.map((column) => `${table}.${column}`)
  );
}
