/**
 * Handler for fs_delete messages.
 * Deletes files or directories (recursive for directories) within a project.
 * Returns FILE_NOT_FOUND if the path doesn't exist.
 */
import { rm, stat, realpath } from "node:fs/promises";
import { join, resolve } from "node:path";
import { ErrorCode } from "@pocketcoder/shared/constants";
import { getProject } from "../db/repositories/projects.js";
import { PathEscapeError } from "../services/filesystem.js";
import { logger } from "../utils/logger.js";
export async function handleFsDelete(message, send) {
    const msg = message;
    const { requestId, sessionId, payload } = msg;
    const { path: relativePath } = payload;
    const project = getProject(sessionId);
    if (!project) {
        send({
            type: "fs_delete_response",
            requestId,
            error: {
                code: ErrorCode.INVALID_REQUEST,
                message: `Project not found: ${sessionId}`,
            },
        });
        return;
    }
    try {
        // Resolve the target path within the project
        const targetPath = join(project.path, relativePath);
        const resolvedProject = await realpath(project.path);
        // First, normalize to prevent .. traversal before checking existence
        const normalized = resolve(targetPath);
        if (!normalized.startsWith(resolvedProject + "/") && normalized !== resolvedProject) {
            throw new PathEscapeError("Path escapes project directory");
        }
        // Check if the target exists
        let targetStat;
        try {
            targetStat = await stat(normalized);
        }
        catch {
            send({
                type: "fs_delete_response",
                requestId,
                error: {
                    code: ErrorCode.FILE_NOT_FOUND,
                    message: `Not found: ${relativePath}`,
                },
            });
            return;
        }
        // For existing files/dirs, do a realpath check to guard against symlink escapes
        const realTarget = await realpath(normalized);
        if (!realTarget.startsWith(resolvedProject + "/") && realTarget !== resolvedProject) {
            throw new PathEscapeError("Path escapes project directory");
        }
        // Delete the file or directory
        await rm(normalized, {
            recursive: targetStat.isDirectory(),
            force: false,
        });
        send({
            type: "fs_delete_response",
            requestId,
            payload: {
                path: relativePath,
            },
        });
    }
    catch (err) {
        if (err instanceof PathEscapeError) {
            send({
                type: "fs_delete_response",
                requestId,
                error: {
                    code: ErrorCode.OUTSIDE_PROJECT_ROOT,
                    message: "Path escapes project directory",
                },
            });
            return;
        }
        const errorMessage = err instanceof Error ? err.message : String(err);
        logger.error(`fs_delete error: ${errorMessage}`);
        send({
            type: "fs_delete_response",
            requestId,
            error: {
                code: ErrorCode.UNKNOWN_ERROR,
                message: errorMessage,
            },
        });
    }
}
//# sourceMappingURL=fs-delete.js.map