import type { SpawnOptions } from "node:child_process";
import type { Server } from "node:http";
import type { RunsApiConnection } from "./runs-api-connections.mjs";

export const CLAUDE_RUNS_MAX_CONCURRENCY: number;
export type ClaudeRunsRequest = {
  input: string;
  instructions: string;
  schema: Record<string, unknown> | null;
  model: string;
  effort: string;
  sessionId: string;
  tools: ClaudeRunsTools | ClaudeRunsRemoteTools | null;
  /** Remote tools: the run's private MCP config file, written by the service. */
  mcpConfigPath?: string;
};
export type ClaudeRunsToolServer = {
  command: string;
  args: string[];
  env: Record<string, string>;
};
export type ClaudeRunsTools = { names: string[]; server: ClaudeRunsToolServer };
/** The run's own remote MCP server and grant (public mode). */
export type ClaudeRunsRemoteTools = {
  names: string[];
  remote: { url: string; authorization: string };
};
export type ClaudeRunsToolLanes = {
  turnDescriptorPath: string;
  server(): ClaudeRunsToolServer | null;
};
export type ClaudeRunsResult = {
  output: string;
  runtime: { provider: string; model: string };
  usage: Record<string, number>;
};
export type ClaudeRunsServer = Server & { stopActiveRuns(): Promise<void> };
export type ClaudeRunsApiOptions = {
  token: string;
  /** Required in loopback mode; the public listener has none. */
  connection?: RunsApiConnection;
  mode?: "loopback" | "public";
  /** The CLI and account root; defaults to the connection's localRoot. */
  root?: string;
  execute?:
    | ((request: ClaudeRunsRequest) => {
        promise: Promise<ClaudeRunsResult>;
        stop(): void;
      })
    | null;
  audit?: (entry: Record<string, unknown>) => void;
  maxConcurrency?: number;
  maxToolConcurrency?: number;
  toolLanes?: ClaudeRunsToolLanes | null;
  checkAuthentication?: (
    configDir: string
  ) => Promise<"READY" | "SIGN_IN_REQUIRED" | "UNAVAILABLE">;
  accounts?: () => string[];
  startRun?: (
    request: ClaudeRunsRequest,
    options: { root: string; configDir: string }
  ) => { promise: Promise<ClaudeRunsResult>; stop(code?: string): void };
  now?: () => number;
};
export function validateClaudeRunsRequest(
  body: unknown,
  /** null: the public rule (claude-* model, low/medium/high effort). */
  models: RunsApiConnection["models"] | null
): ClaudeRunsRequest;
export function endpointToolNames(options: {
  turnDescriptorPath: string;
  sessionId: string;
  /** Absent: every run gets the tools its own turn descriptor allows. */
  toolEndpointIds?: string[];
}): string[] | null;
export function claudeInvocation(
  request: ClaudeRunsRequest,
  root: string,
  mcpSpecPath?: string | null,
  configDir?: string
): { command: string; args: string[]; options: SpawnOptions };
export function claudeAccountDirs(root: string): string[];
export function claudeUsageLimit(
  stdout: string,
  now?: number
): { retryAt: number } | null;
export function parseClaudeResult(
  stdout: string,
  request: ClaudeRunsRequest
): ClaudeRunsResult;
export function startClaudeRun(
  request: ClaudeRunsRequest,
  options: {
    root: string;
    configDir?: string;
    spawnImpl?: (...args: any[]) => any;
    timeoutMs?: number;
  }
): { promise: Promise<ClaudeRunsResult>; stop(code?: string): void };
export function createClaudeRunsApi(
  options: ClaudeRunsApiOptions
): ClaudeRunsServer;
export function startConfiguredClaudeRunsApis(options?: {
  env?: Record<string, string | undefined>;
  diagnostic?: (entry: Record<string, unknown>) => void;
  createApi?: typeof createClaudeRunsApi;
  readToken?: (path: string) => string;
  toolLanes?: ClaudeRunsToolLanes | null;
}): Promise<{ stop(): Promise<void> }>;

export function startPublicClaudeRunsApi(options?: {
  env?: Record<string, string | undefined>;
  diagnostic?: (entry: Record<string, unknown>) => void;
  root?: string;
  createApi?: typeof createClaudeRunsApi;
  readToken?: (path: string) => string;
}): Promise<{ stop(): Promise<void> } | null>;

export function readClaudeAuthentication(options: {
  root: string;
  configDir?: string;
  execFileImpl?: any;
  timeoutMs?: number;
}): Promise<"READY" | "SIGN_IN_REQUIRED" | "UNAVAILABLE">;
