"use strict";
/**
 * Project-root marker detection.
 *
 * The wizard mutates files in `installDir`: it installs SDK dependencies,
 * writes init code, edits source files, persists `.amplitude/` metadata.
 * If the directory isn't actually a project root — the user invoked the
 * wizard from `$HOME`, from `~/dev/` (a multi-project parent), or from
 * a tmpdir — the wizard would scan thousands of files, instrument the
 * wrong codebase, or pollute the user's home dir with `.amplitude/`.
 *
 * We refuse to proceed in that case unless the caller passes `--force`.
 *
 * "Project root" is detected via the presence of any well-known package
 * manifest. The list is the union of what the wizard's `detect` flow
 * already supports (Next.js / Vue / React / Django / Flask / FastAPI /
 * Swift / RN / Android / Flutter / Go / Java / Unreal / Unity / Rails /
 * Laravel / Ruby / Python). One marker is enough.
 *
 * Pure module — no I/O at import time, no UI imports — so the rule can
 * be exercised in isolation by unit tests.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.PROJECT_MARKER_EXTENSIONS = exports.PROJECT_MARKER_PATHS = exports.PROJECT_MARKER_FILES = void 0;
exports.checkProjectGuard = checkProjectGuard;
const fs = __importStar(require("node:fs"));
const os = __importStar(require("node:os"));
const path = __importStar(require("node:path"));
/**
 * Filenames that indicate "this directory is a project root the wizard
 * can reasonably operate on." Add new ones when adding new framework
 * support — keep this list aligned with `FRAMEWORK_REGISTRY`.
 */
exports.PROJECT_MARKER_FILES = [
    'package.json',
    'pyproject.toml',
    'requirements.txt',
    'Pipfile',
    'Cargo.toml',
    'go.mod',
    'Gemfile',
    'pom.xml',
    'build.gradle',
    'build.gradle.kts',
    'Package.swift',
    'pubspec.yaml',
    'composer.json',
];
/**
 * Project markers that live one directory deeper than the install dir.
 * Unity projects keep their version file inside `ProjectSettings/`; the
 * top-level project root has no manifest at all by Unity convention,
 * so without this entry every Unity user is told "no project manifest"
 * even though the framework is supported and detected by
 * `detectUnityProject` (`src/frameworks/unity/utils.ts`).
 */
exports.PROJECT_MARKER_PATHS = [
    // Unity 2017+ — present in every Unity project
    'ProjectSettings/ProjectVersion.txt',
];
/**
 * Project markers identified by file extension at the install-dir root.
 * Unreal Engine names its project file `<ProjectName>.uproject` — the
 * exact filename varies, so a fixed-name match in `PROJECT_MARKER_FILES`
 * doesn't work. We do a single non-recursive `readdir` and check
 * extensions; the cost is bounded by the number of files at the root.
 */
exports.PROJECT_MARKER_EXTENSIONS = [
    // Unreal Engine — project descriptor
    '.uproject',
];
/**
 * Returns `{ ok: true }` when `installDir` looks like a project root the
 * wizard should operate on, or a structured failure with a reason and a
 * human-readable detail string. Pure — no side effects.
 *
 * Specific failure modes:
 *   - `is_home_dir`: installDir is exactly `os.homedir()`. Even if a
 *     marker is present (rare — `package.json` in `$HOME`), refuse,
 *     because the blast radius of `pnpm install` and `Write` tools in
 *     `$HOME` is unacceptable.
 *   - `is_filesystem_root`: installDir is `/`, `C:\`, or similar.
 *   - `no_project_marker`: directory exists but contains no recognized
 *     package manifest. Likely a multi-project parent dir (`~/dev/`)
 *     or a stray location.
 *   - `install_dir_missing`: directory does not exist.
 *
 * Callers can bypass with their own `--force` semantics.
 *
 * `homedir` is injectable for tests; production callers use the default.
 */
function checkProjectGuard(installDir, homedir = os.homedir()) {
    let resolved;
    try {
        resolved = path.resolve(installDir);
    }
    catch {
        return {
            ok: false,
            reason: 'install_dir_missing',
            details: `install dir is unresolvable: ${installDir}`,
        };
    }
    if (!fs.existsSync(resolved)) {
        return {
            ok: false,
            reason: 'install_dir_missing',
            details: `install dir does not exist: ${resolved}`,
        };
    }
    const home = path.resolve(homedir);
    if (resolved === home) {
        return {
            ok: false,
            reason: 'is_home_dir',
            details: 'install dir is the user home directory. The wizard installs SDK ' +
                'dependencies and edits source files — this is almost never what you ' +
                'want from $HOME. Pass `--install-dir <abs-path>` pointing at a real ' +
                'project, or `--force` to bypass.',
        };
    }
    // Filesystem root — `/` on POSIX, `C:\\` etc. on Windows. `path.parse`
    // returns `root` for these cases.
    const parsed = path.parse(resolved);
    if (resolved === parsed.root) {
        return {
            ok: false,
            reason: 'is_filesystem_root',
            details: `install dir is the filesystem root (${resolved}). Pass --install-dir <abs-path> to a real project.`,
        };
    }
    // Look for at least one project marker at the top level. We do NOT
    // recurse: every framework the wizard supports places its manifest
    // either at the root, in a single fixed sub-path (Unity), or as a
    // root-level file with a known extension (Unreal).
    const found = [];
    for (const marker of exports.PROJECT_MARKER_FILES) {
        if (fs.existsSync(path.join(resolved, marker))) {
            found.push(marker);
        }
    }
    for (const subPath of exports.PROJECT_MARKER_PATHS) {
        if (fs.existsSync(path.join(resolved, subPath))) {
            found.push(subPath);
        }
    }
    if (exports.PROJECT_MARKER_EXTENSIONS.length > 0) {
        // Single non-recursive readdir to find any extension-marker file at
        // the root. Wrapped in try/catch so a permissions error on the dir
        // (rare; install-dir was already `existsSync`-confirmed above) falls
        // through to the regular "no marker" path instead of blowing up.
        try {
            for (const entry of fs.readdirSync(resolved)) {
                const ext = path.extname(entry).toLowerCase();
                if (exports.PROJECT_MARKER_EXTENSIONS.some((m) => m.toLowerCase() === ext)) {
                    found.push(entry);
                    break;
                }
            }
        }
        catch {
            // unreadable dir — skip, fall through to no-marker error below
        }
    }
    if (found.length === 0) {
        return {
            ok: false,
            reason: 'no_project_marker',
            details: `install dir has no project manifest (${exports.PROJECT_MARKER_FILES.slice(0, 5).join(', ')}…). ` +
                'This usually means you ran the wizard from a multi-project parent ' +
                'dir or the wrong path. Pass `--install-dir <abs-path>` pointing at ' +
                'the project root, or `--force` to bypass.',
        };
    }
    return { ok: true, markers: found };
}
