/**
 * PR15 CLI Executor 类型契约（skeleton）—— 服务端 Docker per-tenant 沙盒执行白名单 CLI。
 *
 * 用法：把已有成熟 CLI（git / kubectl / psql 只读 / adp-cli）按"argv 模板 + 参数白名单"
 * 注册成 agent 工具；调用时启 Docker 容器（per-user 沙盒），跑 CLI，回收 stdout/stderr，
 * 容器销毁。
 *
 * 详见 docs/modules/agent/02-architecture.md §1.3.4 / PR15 段 + CLI 工具的 "API 化封装" 模式示例。
 *
 * **本文件仅类型 + Service skeleton**，启用前需到位：
 * 1. Docker daemon 在后端节点可访问（sock 挂载 / SDK 鉴权）
 * 2. per-tenant 镜像构建（ffai/cli-runner:git / kubectl / psql / adp-cli）—— Dockerfile 在 infra repo
 * 3. quota 联动（每用户并发 ≤ N，单次 CPU/内存上限）
 * 4. network egress 限制（容器默认 --network=none，白名单走 sidecar proxy）
 */

/** 单参数 schema（argv 模板里 `{name}` 占位符的约束） */
export interface CliParamSchema {
  readonly type: 'integer' | 'string' | 'boolean';
  readonly required?: boolean;
  readonly min?: number;
  readonly max?: number;
  /** string 类型的正则白名单（防注入；如 `^[\w./\-]+$`） */
  readonly pattern?: string;
  /** 枚举白名单 */
  readonly enum?: readonly (string | number)[];
}

/** Docker 沙盒配置 */
export interface CliSandboxSpec {
  readonly image: string; // 例：ffai/cli-runner:git
  readonly workdir?: string; // 容器内 cwd 模板，可含 {org_id} / {user_id} / {repo_slug}
  readonly timeoutSec: number;
  readonly readonly: boolean; // 容器 rootfs 是否只读
  /** 默认 'none'（egress 禁）；白名单走 sidecar */
  readonly network?: 'none' | 'bridge' | 'host';
  /** 资源上限 */
  readonly cpuLimit?: string; // e.g. "1.0"
  readonly memoryLimit?: string; // e.g. "256m"
}

/** 注册到 ToolRegistry 的 CLI 工具元 */
export interface CliToolDefinition {
  readonly name: string;
  readonly description: string;
  /** argv 模板，元素含 `{param}` 占位符（用 paramSchemas 校验填值） */
  readonly template: readonly string[];
  readonly paramSchemas: Readonly<Record<string, CliParamSchema>>;
  readonly sandbox: CliSandboxSpec;
}

/** 单次执行的入参（由 agent 提供） */
export interface CliInvokeArgs {
  readonly toolName: string;
  readonly params: Readonly<Record<string, unknown>>;
  readonly orgId: string;
  readonly userId: string;
}

/** 执行结果 */
export interface CliInvokeResult {
  readonly exitCode: number;
  readonly stdout: string;
  readonly stderr: string;
  readonly durationMs: number;
  readonly timedOut: boolean;
  /** 截断标志（stdout/stderr 超 size 上限时） */
  readonly stdoutTruncated?: boolean;
  readonly stderrTruncated?: boolean;
}

/** 第一批 CLI 工具（PR15 起步 4 个，按 PRD US-503/504/505） */
export const PR15_DEFAULT_CLI_TOOLS: readonly CliToolDefinition[] = [
  {
    name: 'git.log',
    description: '查询 git 仓库提交历史（read-only）。',
    template: ['git', 'log', '--oneline', '-n', '{count}', '--', '{path}'],
    paramSchemas: {
      count: { type: 'integer', required: true, min: 1, max: 1000 },
      path: { type: 'string', required: true, pattern: '^[\\w./\\-]+$' },
    },
    sandbox: {
      image: 'ffai/cli-runner:git',
      workdir: '/repo/{org_id}/{repo_slug}',
      timeoutSec: 30,
      readonly: true,
      network: 'none',
      memoryLimit: '128m',
    },
  },
  {
    name: 'kubectl.get',
    description: '查询 K8s 集群资源状态（read-only）。',
    template: ['kubectl', 'get', '{resource}', '-n', '{namespace}', '-o', 'json'],
    paramSchemas: {
      resource: {
        type: 'string',
        required: true,
        enum: ['pods', 'services', 'deployments', 'jobs', 'configmaps'],
      },
      namespace: { type: 'string', required: true, pattern: '^[a-z0-9\\-]+$' },
    },
    sandbox: {
      image: 'ffai/cli-runner:kubectl',
      timeoutSec: 20,
      readonly: true,
      network: 'bridge', // 需要 K8s apiserver 出口（走 sidecar proxy 限制目标）
      memoryLimit: '128m',
    },
  },
  {
    name: 'psql.query',
    description: '在 read-only replica 上跑 SQL 查询。SELECT only。',
    template: ['psql', '-h', '{host}', '-U', '{user}', '-d', '{db}', '-c', '{sql}'],
    paramSchemas: {
      host: { type: 'string', required: true, pattern: '^[\\w.\\-]+$' },
      user: { type: 'string', required: true, pattern: '^[\\w\\-]+$' },
      db: { type: 'string', required: true, pattern: '^[\\w\\-]+$' },
      sql: { type: 'string', required: true }, // 服务端额外解析 AST 拒非 SELECT
    },
    sandbox: {
      image: 'ffai/cli-runner:psql',
      timeoutSec: 30,
      readonly: true,
      network: 'bridge',
      memoryLimit: '256m',
    },
  },
  {
    name: 'adp.cli',
    description: 'ADP 内部 CLI（read-only 操作）。',
    template: ['adp-cli', '{subcommand}', '--json'],
    paramSchemas: {
      subcommand: {
        type: 'string',
        required: true,
        enum: ['list-systems', 'system-status', 'list-jobs'],
      },
    },
    sandbox: {
      image: 'ffai/cli-runner:adp',
      timeoutSec: 30,
      readonly: true,
      network: 'bridge',
      memoryLimit: '128m',
    },
  },
];
