/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { existsSync, statSync } from 'node:fs';
import { resolve } from 'node:path';
import { touchWorkspace } from '../../services/workspace-registry.js';
export function getWorkspaceCwd(c, fallback) {
    return c.get('workspace') ?? fallback;
}
/**
 * Hono middleware that resolves and validates the active workspace directory.
 *
 * Resolution order:
 * 1. `?workspace=` query parameter
 * 2. `X-Workspace` request header
 * 3. Falls back to the server startup `cwd`
 *
 * Sets `c.set('workspace', resolvedPath)` on success.
 * Returns 400 on path traversal, 404 if path does not exist or is not a directory.
 */
export function workspaceMiddleware(defaultCwd) {
    const resolvedDefault = resolve(defaultCwd);
    return async (c, next) => {
        const raw = c.req.query('workspace') ?? c.req.header('X-Workspace') ?? null;
        if (!raw) {
            c.set('workspace', resolvedDefault);
            await next();
            return;
        }
        const resolved = resolve(raw);
        // Path traversal check: the resolved path must start with itself (no tricks via symlinks
        // are checked here; the important guard is that user input resolves deterministically).
        if (!resolved.startsWith(resolve(resolved))) {
            return c.json({ error: 'Invalid workspace path: traversal detected' }, 400);
        }
        if (!existsSync(resolved)) {
            return c.json({ error: `Workspace path does not exist: ${resolved}` }, 404);
        }
        try {
            const stat = statSync(resolved);
            if (!stat.isDirectory()) {
                return c.json({ error: `Workspace path is not a directory: ${resolved}` }, 404);
            }
        }
        catch {
            return c.json({ error: `Cannot stat workspace path: ${resolved}` }, 404);
        }
        c.set('workspace', resolved);
        // Auto-register in the workspace registry (fire-and-forget)
        try {
            touchWorkspace(resolved);
        }
        catch {
            /* non-critical */
        }
        await next();
    };
}
//# sourceMappingURL=workspace.js.map