// 文件作用域约束：Desktop 端 fs.* 工具默认仅可读写 ~/FFAI Workspace/。
//
// 架构 §1.3.2：细粒度 scope —— fs.read 默认仅 `~/FFAI Workspace/` 目录；
// 用户主动选别的目录才扩展（OS 文件选择器，PR12 内不实现 expand）。

import { app } from "electron";
import * as path from "node:path";
import * as fs from "node:fs/promises";

/** 默认工作区根目录 */
export function getWorkspaceRoot(): string {
  return path.join(app.getPath("home"), "FFAI Workspace");
}

/** 确保工作区根目录存在；幂等 */
export async function ensureWorkspaceRoot(): Promise<string> {
  const root = getWorkspaceRoot();
  await fs.mkdir(root, { recursive: true });
  return root;
}

/**
 * 把用户/LLM 给的路径收敛到 root 内，阻断 `../` 越界。
 * 返回 absolute path；越界 / 绝对路径 / 空 → 抛错。
 *
 * Windows 绝对路径形态（C:\foo / //server/share）跟 POSIX 不同，统一拒绝绝对路径而非
 * 尝试归一化——LLM 工具协议里所有 path 都应该是 workspace 相对路径。
 */
export function resolveSafe(root: string, rel: string): string {
  if (typeof rel !== "string" || rel.length === 0) {
    throw new Error("path_required");
  }
  if (path.isAbsolute(rel) || /^[a-zA-Z]:[\\/]/.test(rel)) {
    // POSIX `/abs/path` + Windows `C:\foo` / `C:/foo`
    throw new Error(`absolute_path_rejected:${rel}`);
  }
  const rootAbs = path.resolve(root);
  const full = path.resolve(rootAbs, rel);
  if (full !== rootAbs && !full.startsWith(rootAbs + path.sep)) {
    throw new Error(`path_escapes_root:${rel}`);
  }
  return full;
}
