import { shq } from "./remote-ssh.mjs";
import { SEATS_HOME_REL, SEAT_STATE_REL, SEAT_ACCOUNTS_REL, SEAT_TRUSTED_CONFIG_DIR, SEAT_LAUNCHER_BIN } from "./seat-constants.mjs";

const SAFE_ID_RE = /^[a-z0-9][a-z0-9._-]*$/i;
const PATH_COMPONENT_RE = /^[A-Za-z0-9._-]+$/;
const SHELL_VAR_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
const SHELL_METACHAR_RE = /[\x00-\x1f\x7f$`'"\\;|&<>(){}[\]*?!~\n\r]/;
const HOME_EXPR_PREFIX = '"$HOME/';

function assertSafeId(label, value) {
  const v = String(value ?? "");
  if (!SAFE_ID_RE.test(v)) throw new Error(`unsafe ${label}: ${value}`);
  return v;
}

export function validateHomeRelPath(relPath) {
  const raw = String(relPath ?? "");
  if (raw.startsWith("/")) throw new Error(`unsafe home-relative path: ${relPath}`);
  const rel = raw.replace(/^\/+/, "");
  if (!rel) throw new Error(`unsafe home-relative path: ${relPath}`);
  if (rel.includes("..")) throw new Error(`unsafe home-relative path: ${relPath}`);
  if (SHELL_METACHAR_RE.test(rel)) throw new Error(`unsafe home-relative path: ${relPath}`);
  const parts = rel.split("/");
  for (const part of parts) {
    if (!part || part === "." || part === "..") throw new Error(`unsafe home-relative path: ${relPath}`);
    if (!PATH_COMPONENT_RE.test(part)) throw new Error(`unsafe home-relative path: ${relPath}`);
  }
  return rel;
}

function assertShellVarName(varName) {
  const v = String(varName ?? "");
  if (!SHELL_VAR_RE.test(v)) throw new Error(`unsafe shell variable: ${varName}`);
  return v;
}

export function homeRel(...segments) {
  return segments.filter(Boolean).join("/");
}

export function shellHomePath(relPath) {
  const rel = validateHomeRelPath(relPath);
  return `${HOME_EXPR_PREFIX}${rel}"`;
}

export function isShellHomePathExpr(value) {
  if (typeof value !== "string") return false;
  if (!value.startsWith(HOME_EXPR_PREFIX) || !value.endsWith('"') || value.length <= HOME_EXPR_PREFIX.length + 1) {
    return false;
  }
  try {
    validateHomeRelPath(value.slice(HOME_EXPR_PREFIX.length, -1));
    return true;
  } catch {
    return false;
  }
}

export function shellPathAssign(varName, pathOrExpr) {
  assertShellVarName(varName);
  if (isShellHomePathExpr(pathOrExpr)) return `${varName}=${pathOrExpr}`;
  return `${varName}=${shq(pathOrExpr)}`;
}

export function seatHomeShellPath(seatId) {
  assertSafeId("seatId", seatId);
  return shellHomePath(homeRel(SEATS_HOME_REL, seatId));
}

export function seatCheckoutShellPath(seatId) {
  assertSafeId("seatId", seatId);
  return shellHomePath(homeRel(SEATS_HOME_REL, seatId, "repo"));
}

export function seatStateDirShellPath(seatId) {
  assertSafeId("seatId", seatId);
  return shellHomePath(homeRel(SEAT_STATE_REL, seatId));
}

export function seatTmuxSocketShellPath(seatId) {
  assertSafeId("seatId", seatId);
  return shellHomePath(homeRel(SEAT_STATE_REL, seatId, "tmux.sock"));
}

export function seatTrustedConfigShellDir(seatId) {
  assertSafeId("seatId", seatId);
  return shellHomePath(homeRel(SEAT_STATE_REL, seatId, SEAT_TRUSTED_CONFIG_DIR));
}

export function seatProfileShellPath(accountSlug, seatId) {
  assertSafeId("accountSlug", accountSlug);
  assertSafeId("seatId", seatId);
  return shellHomePath(homeRel(SEAT_ACCOUNTS_REL, accountSlug, seatId));
}

export function launcherShellPath() {
  return SEAT_LAUNCHER_BIN;
}

export function claudeBinShellPath() {
  return shellHomePath(homeRel(".local", "bin", "claude"));
}

export function guardBinShellDir() {
  return shellHomePath(homeRel(".local", "share", "overdeck", "seat-guard", "current", "bin"));
}

export function seatGuardRootShellPath() {
  return shellHomePath(homeRel(".local", "share", "overdeck", "seat-guard", "current"));
}
