-- ============ AgentKind ============
CREATE TABLE acp_agent_kinds (
  id              UUID PRIMARY KEY,
  name            TEXT NOT NULL UNIQUE,
  display_name    TEXT NOT NULL,
  description     TEXT NOT NULL DEFAULT '',
  binary_path     TEXT NOT NULL,
  args            TEXT[] NOT NULL DEFAULT '{}',
  encrypted_env   BYTEA,
  enabled         BOOLEAN NOT NULL DEFAULT TRUE,
  created_by      UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
  created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at      TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_acp_agent_kinds_enabled ON acp_agent_kinds(enabled) WHERE enabled = TRUE;

-- ============ Prerequisites for composite FK ============
ALTER TABLE issues       ADD CONSTRAINT issues_project_id_unique       UNIQUE (project_id, id);
ALTER TABLE requirements ADD CONSTRAINT requirements_project_id_unique UNIQUE (project_id, id);

-- ============ Sessions ============
CREATE TABLE acp_sessions (
  id                 UUID PRIMARY KEY,
  workspace_id       UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
  project_id         UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
  agent_kind_id      UUID NOT NULL REFERENCES acp_agent_kinds(id) ON DELETE RESTRICT,
  user_id            UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
  issue_id           UUID,
  requirement_id     UUID,
  agent_session_id   TEXT,
  branch             TEXT NOT NULL,
  cwd_path           TEXT NOT NULL,
  is_main_worktree   BOOLEAN NOT NULL DEFAULT FALSE,
  status             TEXT NOT NULL,
  pid                INT,
  exit_code          INT,
  last_error         TEXT,
  started_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
  ended_at           TIMESTAMPTZ,
  CONSTRAINT acp_sessions_status_check CHECK (status IN ('starting','running','crashed','exited')),
  CONSTRAINT acp_sessions_issue_project_fk
    FOREIGN KEY (project_id, issue_id)
    REFERENCES issues (project_id, id) MATCH SIMPLE ON DELETE SET NULL,
  CONSTRAINT acp_sessions_req_project_fk
    FOREIGN KEY (project_id, requirement_id)
    REFERENCES requirements (project_id, id) MATCH SIMPLE ON DELETE SET NULL
);
CREATE INDEX idx_acp_sessions_workspace_status ON acp_sessions(workspace_id, status);
CREATE INDEX idx_acp_sessions_user_status      ON acp_sessions(user_id, status);
CREATE INDEX idx_acp_sessions_issue            ON acp_sessions(issue_id)       WHERE issue_id IS NOT NULL;
CREATE INDEX idx_acp_sessions_requirement      ON acp_sessions(requirement_id) WHERE requirement_id IS NOT NULL;

-- ============ Workspaces main worktree mutex ============
ALTER TABLE workspaces ADD COLUMN active_main_session_id UUID;
ALTER TABLE workspaces
  ADD CONSTRAINT workspaces_active_main_session_fk
  FOREIGN KEY (active_main_session_id)
  REFERENCES acp_sessions(id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;

-- ============ Events ============
CREATE TABLE acp_events (
  id                BIGSERIAL PRIMARY KEY,
  session_id        UUID NOT NULL REFERENCES acp_sessions(id) ON DELETE CASCADE,
  direction         TEXT NOT NULL,
  rpc_kind          TEXT NOT NULL,
  method            TEXT,
  payload           JSONB NOT NULL,
  payload_size      INT NOT NULL,
  truncated         BOOLEAN NOT NULL DEFAULT FALSE,
  created_at        TIMESTAMPTZ NOT NULL DEFAULT now(),
  CONSTRAINT acp_events_direction_check CHECK (direction IN ('in','out')),
  CONSTRAINT acp_events_kind_check      CHECK (rpc_kind IN ('request','response','notification','error'))
);
CREATE INDEX idx_acp_events_session_id ON acp_events(session_id, id);
CREATE INDEX idx_acp_events_created_at ON acp_events(created_at);
