import {
  BLOCKED_EDIT_MODE,
  BRANCH_PR_EDIT_MODE,
  resolveInProgressEditMode
} from "./chunk-B7YJYJKG.js";
import {
  INIT_PATTERNS
} from "./chunk-NAP6CFSO.js";
import {
  INIT_PATHS
} from "./chunk-ZHCZHZH3.js";
import {
  createGitForPath
} from "./chunk-2UFQ3A3C.js";
import {
  parseYAML
} from "./chunk-NRIZR3A7.js";
import {
  WU_PATHS,
  defaultWorktreeFrom
} from "./chunk-6HO4GWJE.js";
import {
  FILE_SYSTEM
} from "./chunk-DWMLTXKQ.js";
import {
  WU_EXPOSURE_VALUES,
  WU_STATUS,
  getConfig
} from "./chunk-V6OJGLBA.js";
import {
  die
} from "./chunk-RXRKBBSM.js";

// src/wu-edit-validators.ts
import { existsSync, readFileSync } from "fs";
import { resolve, join, relative, isAbsolute } from "path";
var EDIT_MODE = {
  /** Ready WUs: Use micro-worktree on main (existing behavior) */
  MICRO_WORKTREE: "micro_worktree",
  /** In-progress worktree WUs: Apply edits directly in active worktree (WU-1365) */
  WORKTREE: "worktree",
  /** In-progress branch-pr WUs: apply edits directly on the claimed branch */
  BRANCH_PR: BRANCH_PR_EDIT_MODE
};
function validateDoneWUEdits(opts) {
  const disallowedEdits = [];
  if (opts.specFile) disallowedEdits.push("--spec-file");
  if (opts.description) disallowedEdits.push("--description");
  if (opts.acceptance && Array.isArray(opts.acceptance) && opts.acceptance.length > 0) {
    disallowedEdits.push("--acceptance");
  }
  if (opts.notes) disallowedEdits.push("--notes");
  if (opts.codePaths && Array.isArray(opts.codePaths) && opts.codePaths.length > 0) {
    disallowedEdits.push("--code-paths");
  }
  if (opts.risks && Array.isArray(opts.risks) && opts.risks.length > 0) {
    disallowedEdits.push("--risks");
  }
  if (opts.lane) disallowedEdits.push("--lane");
  if (opts.type) disallowedEdits.push("--type");
  if (opts.priority) disallowedEdits.push("--priority");
  if (opts.testPathsManual && Array.isArray(opts.testPathsManual) && opts.testPathsManual.length > 0) {
    disallowedEdits.push("--test-paths-manual");
  }
  if (opts.testPathsUnit && Array.isArray(opts.testPathsUnit) && opts.testPathsUnit.length > 0) {
    disallowedEdits.push("--test-paths-unit");
  }
  if (opts.testPathsE2e && Array.isArray(opts.testPathsE2e) && opts.testPathsE2e.length > 0) {
    disallowedEdits.push("--test-paths-e2e");
  }
  return {
    valid: disallowedEdits.length === 0,
    disallowedEdits
  };
}
function validateExposureValue(exposure) {
  const validValues = WU_EXPOSURE_VALUES;
  if (!validValues.includes(exposure)) {
    return {
      valid: false,
      error: `Invalid exposure value: "${exposure}"

Valid values: ${WU_EXPOSURE_VALUES.join(", ")}`
    };
  }
  return { valid: true };
}
function validateInitiativeFormat(initId) {
  if (!INIT_PATTERNS.INIT_ID.test(initId)) {
    die(
      `Invalid Initiative ID format: "${initId}"

Expected format: INIT-<number> or INIT-<NAME> (e.g., INIT-001, INIT-TOOLING)`
    );
  }
}
function validateInitiativeExists(initId) {
  const initPath = INIT_PATHS.INITIATIVE(initId);
  if (!existsSync(initPath)) {
    die(`Initiative not found: ${initId}

File does not exist: ${initPath}`);
  }
  return initPath;
}
function validateWUEditable(id) {
  const wuPath = WU_PATHS.WU(id);
  if (!existsSync(wuPath)) {
    die(`WU ${id} not found at ${wuPath}

Ensure the WU exists and you're in the repo root.`);
  }
  const content = readFileSync(wuPath, { encoding: FILE_SYSTEM.ENCODING });
  const wu = parseYAML(content);
  if (wu.status === WU_STATUS.DONE) {
    return { wu, editMode: EDIT_MODE.MICRO_WORKTREE, isDone: true };
  }
  if (wu.status === WU_STATUS.IN_PROGRESS) {
    const editMode = resolveInProgressEditMode(
      typeof wu.claimed_mode === "string" ? wu.claimed_mode : void 0
    );
    if (editMode === BLOCKED_EDIT_MODE) {
      die(
        `Cannot edit branch-only WU ${id} via wu:edit.

WUs claimed with claimed_mode='branch-only' cannot be edited via wu:edit.
To modify the spec, edit the file directly on the lane branch and commit.`
      );
    }
    if (editMode === EDIT_MODE.BRANCH_PR) {
      return { wu, editMode: EDIT_MODE.BRANCH_PR, isDone: false };
    }
    const worktreeRelPath = defaultWorktreeFrom(wu);
    if (worktreeRelPath) {
      const worktreeWuPath = join(resolve(worktreeRelPath), WU_PATHS.WU(id));
      if (existsSync(worktreeWuPath)) {
        const worktreeContent = readFileSync(worktreeWuPath, {
          encoding: FILE_SYSTEM.ENCODING
        });
        const worktreeWu = parseYAML(worktreeContent);
        return { wu: worktreeWu, editMode: EDIT_MODE.WORKTREE, isDone: false };
      }
    }
    return { wu, editMode: EDIT_MODE.WORKTREE, isDone: false };
  }
  if (wu.status === WU_STATUS.READY) {
    return { wu, editMode: EDIT_MODE.MICRO_WORKTREE, isDone: false };
  }
  die(
    `Cannot edit WU ${id}: status is '${wu.status}'.

Only WUs in '${WU_STATUS.READY}' or '${WU_STATUS.IN_PROGRESS}' (worktree mode) can be edited.`
  );
}
function validateWorktreeExists(worktreePath, id) {
  if (!existsSync(worktreePath)) {
    die(
      `Cannot edit WU ${id}: worktree path missing from disk.

Expected worktree at: ${worktreePath}

The worktree may have been removed or the path is incorrect.
If the worktree was accidentally deleted, you may need to re-claim the WU.`
    );
  }
}
async function validateWorktreeClean(worktreePath, id) {
  try {
    const gitAdapter = createGitForPath(worktreePath);
    const status = (await gitAdapter.raw(["status", "--porcelain"])).trim();
    if (status !== "") {
      die(
        `Cannot edit WU ${id}: worktree has uncommitted changes.

Uncommitted changes in ${worktreePath}:
${status}

Commit or discard your changes before editing the WU spec:
  cd ${worktreePath}
  git add . && git commit -m "wip: save progress"

Then retry wu:edit.`
      );
    }
  } catch (err) {
    die(
      `Cannot edit WU ${id}: failed to check worktree status.

Error: ${err.message}

Worktree path: ${worktreePath}`
    );
  }
}
async function validateWorktreeBranch(worktreePath, expectedBranch, id) {
  try {
    const gitAdapter = createGitForPath(worktreePath);
    const actualBranch = (await gitAdapter.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
    if (actualBranch !== expectedBranch) {
      die(
        `Cannot edit WU ${id}: worktree branch does not match expected lane branch.

Expected branch: ${expectedBranch}
Actual branch:   ${actualBranch}

This may indicate a corrupted worktree state.
Verify the worktree is correctly set up for this WU.`
      );
    }
  } catch (err) {
    die(
      `Cannot edit WU ${id}: failed to check worktree branch.

Error: ${err.message}

Worktree path: ${worktreePath}`
    );
  }
}
function isPathWithin(rootPath, candidatePath) {
  const relativePath = relative(rootPath, candidatePath);
  return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
}
function validateWorktreeExecutionContext(currentCwd, worktreePath, id, retryCommand) {
  const resolvedCwd = resolve(currentCwd);
  const resolvedWorktreePath = resolve(worktreePath);
  if (isPathWithin(resolvedWorktreePath, resolvedCwd)) {
    return;
  }
  const safeRetryCommand = typeof retryCommand === "string" && retryCommand.trim().length > 0 ? retryCommand.trim() : `pnpm wu:edit --id ${id} <edit-flags>`;
  die(
    `Cannot edit in_progress WU ${id} from this checkout.

Current directory: ${resolvedCwd}
Claimed worktree: ${resolvedWorktreePath}

Run from the claimed worktree and retry:
  cd ${resolvedWorktreePath}
  ${safeRetryCommand}`
  );
}
function toPosixPath(filePath) {
  return filePath.replace(/\\/g, "/");
}
function getRuntimePathClassification(projectRoot) {
  const config = getConfig({ projectRoot });
  const stateEventsPath = toPosixPath(`${config.state.stateDir}/wu-events.jsonl`);
  const backlogPath = toPosixPath(config.directories.backlogPath);
  const statusPath = toPosixPath(config.directories.statusPath);
  const wuDirPrefix = toPosixPath(config.directories.wuDir).replace(/\/?$/, "/");
  return {
    nonScopeRelevantPaths: /* @__PURE__ */ new Set([stateEventsPath, backlogPath, statusPath]),
    wuDirPrefix
  };
}
function hasScopeRelevantBranchChanges(changedFiles) {
  const { nonScopeRelevantPaths, wuDirPrefix } = getRuntimePathClassification(process.cwd());
  return changedFiles.some((filePath) => {
    const normalized = toPosixPath(filePath.trim());
    if (!normalized) {
      return false;
    }
    if (nonScopeRelevantPaths.has(normalized)) {
      return false;
    }
    return !normalized.startsWith(wuDirPrefix);
  });
}
function normalizeReplaceCodePathsArgv(argv) {
  const normalized = [...argv];
  for (let i = 0; i < normalized.length; i += 1) {
    if (normalized[i] !== "--replace-code-paths") {
      continue;
    }
    const next = normalized[i + 1];
    if (next && !next.startsWith("-")) {
      normalized.splice(i + 1, 0, "--code-paths");
      i += 1;
    }
  }
  return normalized;
}

export {
  EDIT_MODE,
  validateDoneWUEdits,
  validateExposureValue,
  validateInitiativeFormat,
  validateInitiativeExists,
  validateWUEditable,
  validateWorktreeExists,
  validateWorktreeClean,
  validateWorktreeBranch,
  validateWorktreeExecutionContext,
  hasScopeRelevantBranchChanges,
  normalizeReplaceCodePathsArgv
};
