/**
 * src/server/router.ts — URL pattern matching + method dispatch for Planu HTTP API
 *
 * SPEC-610: Planu HTTP API — lightweight router using Node built-in URL
 * No framework dependencies — pure Node.js http module.
 */
/**
 * Minimal router — registers routes by HTTP method + path pattern and
 * dispatches incoming requests to the first matching handler.
 *
 * Path patterns support `:name` named segments, e.g. `/api/specs/:id/status`.
 */
export class Router {
    routes = [];
    /** Register a GET handler. */
    get(path, handler) {
        this.register('GET', path, handler);
    }
    /** Register a POST handler. */
    post(path, handler) {
        this.register('POST', path, handler);
    }
    /** Register a PATCH handler. */
    patch(path, handler) {
        this.register('PATCH', path, handler);
    }
    register(method, path, handler) {
        const { pattern, paramNames } = compilePattern(path);
        this.routes.push({ method, pattern, paramNames, handler });
    }
    /**
     * Dispatch an incoming request to the matching handler.
     * Returns true if a route matched, false otherwise.
     */
    async dispatch(req, res) {
        const rawUrl = req.url ?? '/';
        // Use a placeholder base since we only care about pathname + search
        const url = new URL(rawUrl, 'http://localhost');
        const pathname = url.pathname;
        const method = req.method ?? 'GET';
        for (const route of this.routes) {
            if (route.method !== method) {
                continue;
            }
            const match = pathname.match(route.pattern);
            if (!match) {
                continue;
            }
            const params = {};
            route.paramNames.forEach((name, i) => {
                const value = match[i + 1];
                if (value !== undefined) {
                    params[name] = decodeURIComponent(value);
                }
            });
            const ctx = {
                method,
                pathname,
                searchParams: url.searchParams,
                params,
                req,
                res,
            };
            await route.handler(ctx);
            return true;
        }
        return false;
    }
}
/**
 * Convert an Express-style path (e.g. `/api/specs/:id/status`) to a
 * RegExp + ordered list of param names.
 */
function compilePattern(path) {
    const paramNames = [];
    // Escape dots, replace :param with capture group
    const regexStr = path
        .replace(/\./g, '\\.')
        .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_match, name) => {
        paramNames.push(name);
        return '([^/]+)';
    });
    // Anchor the pattern to match the full pathname
    const pattern = new RegExp(`^${regexStr}$`);
    return { pattern, paramNames };
}
//# sourceMappingURL=router.js.map