/**
 * P0 Core Tool Implementations
 * 
 * file_list, file_read, file_write, file_move, exec, process_list, sysinfo.
 * These map to C-002 through C-011 in the backlog.
 */

import * as fs from "node:fs";
import * as path from "node:path";
import { execSync, spawn } from "node:child_process";
import * as os from "node:os";

// ── C-002: file_list ────────────────────────────────────────
export async function file_list(args: {
  path: string;
  recursive?: boolean;
}): Promise<any> {
  const dir = args.path || ".";
  const entries = fs.readdirSync(dir, { withFileTypes: true });
  const result = entries.map(e => ({
    name: e.name,
    type: e.isDirectory() ? "dir" : e.isFile() ? "file" : "other",
    size: e.isFile() ? fs.statSync(path.join(dir, e.name)).size : undefined,
  }));
  return { path: dir, entries: result, count: result.length };
}

// ── C-003: file_read ────────────────────────────────────────
export async function file_read(args: {
  path: string;
  encoding?: string;
  offset?: number;
  limit?: number;
}): Promise<any> {
  const encoding = (args.encoding === "base64" ? "base64" : "utf8") as BufferEncoding;
  let content = fs.readFileSync(args.path, encoding);
  if (encoding === "utf8") {
    const lines = (content as string).split("\n");
    const start = args.offset ?? 0;
    const end = args.limit ? start + args.limit : lines.length;
    content = lines.slice(start, end).join("\n");
  }
  return { path: args.path, content, size: fs.statSync(args.path).size };
}

// ── C-004: file_write ───────────────────────────────────────
export async function file_write(args: {
  path: string;
  content: string;
  encoding?: string;
}): Promise<any> {
  const encoding = args.encoding === "base64" ? "base64" : "utf8";
  fs.mkdirSync(path.dirname(args.path), { recursive: true });
  fs.writeFileSync(args.path, args.content, encoding as BufferEncoding);
  return { ok: true, path: args.path, size: fs.statSync(args.path).size };
}

// ── C-005: file_move ────────────────────────────────────────
export async function file_move(args: {
  from: string;
  to: string;
}): Promise<any> {
  fs.mkdirSync(path.dirname(args.to), { recursive: true });
  fs.renameSync(args.from, args.to);
  return { ok: true, from: args.from, to: args.to };
}

// ── C-008: exec ─────────────────────────────────────────────
export async function exec(args: {
  command: string;
  cwd?: string;
  timeout?: number;
}): Promise<any> {
  const timeout = args.timeout ?? 30000;
  try {
    const stdout = execSync(args.command, {
      cwd: args.cwd ?? process.cwd(),
      timeout,
      encoding: "utf8",
      maxBuffer: 10 * 1024 * 1024, // 10MB
      stdio: ["pipe", "pipe", "pipe"],
    });
    return { ok: true, stdout: stdout.toString(), stderr: "" };
  } catch (err: any) {
    return {
      ok: false,
      stdout: err.stdout?.toString() ?? "",
      stderr: err.stderr?.toString() ?? "",
      exitCode: err.status ?? -1,
      signal: err.signal,
    };
  }
}

// ── C-010: process_list ─────────────────────────────────────
export async function process_list(args: {
  filter?: string;
}): Promise<any> {
  let stdout: string;
  try {
    if (process.platform === "win32") {
      stdout = execSync("tasklist /FO CSV /NH", { encoding: "utf8" }).toString();
    } else {
      stdout = execSync("ps aux --no-headers", { encoding: "utf8" }).toString();
    }
  } catch {
    return { error: "Failed to list processes" };
  }

  const processes = stdout.trim().split("\n").map(line => {
    if (process.platform === "win32") {
      const [name, pid, , mem] = line.replace(/"/g, "").split(",");
      return { name: name?.trim(), pid: Number(pid), mem: mem?.trim() };
    }
    const parts = line.trim().split(/\s+/);
    return { user: parts[0], pid: Number(parts[1]), cpu: parts[2], mem: parts[3], name: parts[10] };
  });

  const filtered = args.filter
    ? processes.filter(p => p.name?.toLowerCase().includes(args.filter!.toLowerCase()))
    : processes.slice(0, 50);

  return { count: filtered.length, processes: filtered };
}

// ── C-011: sysinfo ──────────────────────────────────────────
export async function sysinfo(_args: {}): Promise<any> {
  const cpuUsage = os.loadavg();
  const totalMem = os.totalmem();
  const freeMem = os.freemem();
  const uptime = os.uptime();

  return {
    hostname: os.hostname(),
    platform: os.platform(),
    arch: os.arch(),
    cpus: os.cpus().length,
    loadavg: cpuUsage,
    memory: {
      total: totalMem,
      free: freeMem,
      used: totalMem - freeMem,
      percent: Math.round(((totalMem - freeMem) / totalMem) * 100),
    },
    uptime,
    node: process.version,
  };
}
