// Copyright (c) 2026 Hellmai Ltd
// SPDX-License-Identifier: AGPL-3.0-only
/**
 * @file path-utils.ts
 * Path normalization and allowlist utilities for enforcement hooks.
 *
 * Single responsibility: normalize file paths and check allowlist membership.
 * Split from enforcement-checks.ts (WU-2127).
 */
import * as path from 'node:path';
import * as os from 'node:os';
import { ENV_VARS } from '@lumenflow/core/wu-constants';
const GIT_STATUS_QUOTE = '"';
const PATH_PREFIX_CURRENT_DIR = './';
const PATH_SEPARATOR_WINDOWS = '\\';
const PATH_SEPARATOR_POSIX = '/';
const HOME_PATH_PREFIX = '~';
export function normalizeDirectorySegment(value, fallback) {
    const normalized = value.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '');
    return normalized.length > 0 ? normalized : fallback;
}
export function ensureRepoRelativePrefix(value) {
    const normalized = value.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '');
    return normalized.length > 0 ? `${normalized}/` : '';
}
export function stripWrappingQuotes(value) {
    if (value.startsWith(GIT_STATUS_QUOTE) && value.endsWith(GIT_STATUS_QUOTE) && value.length >= 2) {
        return value.slice(1, -1);
    }
    return value;
}
export function normalizeRepoRelativePath(value) {
    const withoutQuotes = stripWrappingQuotes(value.trim());
    const normalizedSeparators = withoutQuotes
        .split(PATH_SEPARATOR_WINDOWS)
        .join(PATH_SEPARATOR_POSIX);
    if (normalizedSeparators.startsWith(PATH_PREFIX_CURRENT_DIR)) {
        return normalizedSeparators.slice(PATH_PREFIX_CURRENT_DIR.length);
    }
    return normalizedSeparators;
}
function resolveHomeDirectory(homeDir) {
    if (homeDir && homeDir.length > 0) {
        return homeDir;
    }
    const envHome = process.env[ENV_VARS.HOME] ?? process.env[ENV_VARS.USERPROFILE];
    if (envHome && envHome.length > 0) {
        return envHome;
    }
    try {
        const detectedHome = os.homedir();
        return detectedHome.length > 0 ? detectedHome : undefined;
    }
    catch {
        return undefined;
    }
}
/**
 * Expand leading "~" in tool file paths without any vendor-specific path rules.
 * Unknown "~user" style inputs are left unchanged.
 */
export function expandHomeRelativePath(value, options = {}) {
    const trimmedValue = value.trim();
    if (trimmedValue === HOME_PATH_PREFIX) {
        return resolveHomeDirectory(options.homeDir) ?? trimmedValue;
    }
    if (!trimmedValue.startsWith('~/') && !trimmedValue.startsWith('~\\')) {
        return trimmedValue;
    }
    const homeDirectory = resolveHomeDirectory(options.homeDir);
    if (!homeDirectory) {
        return trimmedValue;
    }
    const relativeSuffix = trimmedValue.slice(2);
    const normalizedSuffix = relativeSuffix.replace(/[\\/]/g, path.sep);
    return normalizedSuffix.length > 0 ? path.join(homeDirectory, normalizedSuffix) : homeDirectory;
}
/**
 * Resolve tool-provided file paths to canonical absolute paths.
 * Handles home-relative paths and relative paths against the provided cwd.
 */
export function resolveToolInputPath(value, options = {}) {
    const cwd = options.cwd ?? process.cwd();
    const expandedPath = expandHomeRelativePath(value, { homeDir: options.homeDir });
    return path.resolve(cwd, expandedPath);
}
/**
 * Check if a resolved path matches the main-write allowlist.
 *
 * @param resolvedPath - Absolute resolved path to check
 * @param mainRepoPath - Absolute path to the main repo root
 * @param allowlistPrefixes - List of repo-relative prefixes that are allowed
 * @returns True if the path is in the allowlist
 */
export function isAllowlistedPath(resolvedPath, mainRepoPath, allowlistPrefixes) {
    const repoPrefix = mainRepoPath + path.sep;
    if (!resolvedPath.startsWith(repoPrefix)) {
        return false;
    }
    const relativePath = resolvedPath.slice(repoPrefix.length);
    return allowlistPrefixes.some((prefix) => relativePath.startsWith(prefix));
}
//# sourceMappingURL=path-utils.js.map