/**
 * Project detection for `mcpctl skills sync`. Walks up from cwd looking
 * for a `.mcpctl-project` file (single line, project name). Written by
 * `mcpctl config claude --project X` at project setup time.
 *
 * We deliberately don't probe git remotes, env vars, or config heuristics —
 * the marker file is the one true source. If you want a different project
 * for a sync, pass `--project` explicitly.
 */
import { readFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';

export const MARKER_FILENAME = '.mcpctl-project';

/**
 * Walk up from `start` (default: cwd) looking for the marker file. Returns
 * the project name (file contents, trimmed) or null if the walk reaches the
 * root without finding one. We stop at the filesystem root and at the user's
 * home directory — searching above $HOME doesn't make sense for a per-user
 * tool.
 */
export async function findProjectMarker(start: string = process.cwd(), homeDir?: string): Promise<{ project: string; markerPath: string } | null> {
  const home = homeDir ?? process.env['HOME'];
  let dir = start;
  // Defense against broken or pathological inputs.
  if (!dir || dir === '/') return null;

  // Bound the walk: 50 levels is generous; protects against symlink loops.
  for (let i = 0; i < 50; i++) {
    const candidate = join(dir, MARKER_FILENAME);
    try {
      const raw = await readFile(candidate, 'utf-8');
      const project = raw.split('\n')[0]?.trim() ?? '';
      if (project.length === 0) return null;
      return { project, markerPath: candidate };
    } catch (err: unknown) {
      if (!isNotFoundError(err)) throw err;
    }

    if (home && dir === home) return null;
    const parent = dirname(dir);
    if (parent === dir) return null; // reached root
    dir = parent;
  }
  return null;
}

/**
 * Write the marker file. Idempotent — overwriting with the same value is
 * a no-op from the caller's perspective. Used by
 * `mcpctl config claude --project X`.
 */
export async function writeProjectMarker(dir: string, project: string): Promise<string> {
  const path = join(dir, MARKER_FILENAME);
  const { writeFile } = await import('node:fs/promises');
  await writeFile(path, project + '\n', 'utf-8');
  return path;
}

function isNotFoundError(err: unknown): boolean {
  return typeof err === 'object' && err !== null && (err as { code?: string }).code === 'ENOENT';
}
