/*
 * 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, readFileSync } from 'node:fs';
import { join, extname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { serve } from '@hono/node-server';
import { touchWorkspace } from '../services/workspace-registry.js';
import { workspaceMiddleware } from './middleware/workspace.js';
import { pingRoute } from './routes/ping.js';
import { detectRoute } from './routes/detect.js';
import { profilesRoute } from './routes/profiles.js';
import { toolsRoute } from './routes/tools.js';
import { configRoutes } from './routes/config.js';
import { tasksRoutes } from './routes/tasks.js';
import { workflowsRoutes } from './routes/workflows.js';
import { recordsRoute } from './routes/records.js';
import { initRoute } from './routes/init.js';
import { statusRoute } from './routes/status.js';
import { delegationRoute } from './routes/delegation.js';
import { eventsRoute } from './routes/events.js';
import { rolesRoute } from './routes/roles.js';
import { spawnRoute } from './routes/spawn.js';
import { workspacesRoute } from './routes/workspaces.js';
import { artifactsRoute } from './routes/artifacts.js';
import { chatRoute } from './routes/chat.js';
import { gitRoute } from './routes/git.js';
import { mcpRoute } from './routes/mcp.js';
import { filesRoute } from './routes/files.js';
import { insightsRoute } from './routes/insights.js';
import { contextRoute } from './routes/context.js';
export function createBridgeApp(cwd) {
    const app = new Hono();
    app.use('*', cors({ origin: '*', allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'] }));
    const api = new Hono();
    // Apply workspace middleware to all API routes — resolves active workspace from
    // query param, header, or defaults to the server startup cwd.
    api.use('*', workspaceMiddleware(cwd));
    api.route('/ping', pingRoute(cwd));
    api.route('/detect', detectRoute(cwd));
    api.route('/profiles', profilesRoute(cwd));
    api.route('/tools', toolsRoute(cwd));
    api.route('/config', configRoutes(cwd));
    api.route('/init', initRoute(cwd));
    api.route('/tasks', tasksRoutes(cwd));
    api.route('/workflows', workflowsRoutes(cwd));
    api.route('/records', recordsRoute(cwd));
    api.route('/status', statusRoute(cwd));
    api.route('/roles', rolesRoute(cwd));
    api.route('/delegation', delegationRoute(cwd));
    api.route('/spawn', spawnRoute(cwd));
    api.route('/events', eventsRoute(cwd));
    api.route('/workspaces', workspacesRoute());
    api.route('/artifacts', artifactsRoute(cwd));
    api.route('/chat', chatRoute(cwd));
    api.route('/git', gitRoute(cwd));
    api.route('/mcp', mcpRoute(cwd));
    api.route('/files', filesRoute(cwd));
    api.route('/insights', insightsRoute(cwd));
    api.route('/context', contextRoute(cwd));
    app.route('/api/v1', api);
    return app;
}
const MIME_TYPES = {
    '.html': 'text/html',
    '.js': 'application/javascript',
    '.css': 'text/css',
    '.json': 'application/json',
    '.svg': 'image/svg+xml',
    '.png': 'image/png',
    '.ico': 'image/x-icon',
};
function resolveAppDist() {
    const thisFile = fileURLToPath(import.meta.url);
    const candidate = join(thisFile, '..', '..', '..', 'app', 'dist');
    return existsSync(candidate) ? candidate : null;
}
function serveStatic(app, staticDir) {
    app.get('*', (c) => {
        const path = c.req.path === '/' ? '/index.html' : c.req.path;
        const filePath = join(staticDir, path);
        if (existsSync(filePath)) {
            const content = readFileSync(filePath);
            const mime = MIME_TYPES[extname(filePath)] ?? 'application/octet-stream';
            return c.body(content, { headers: { 'Content-Type': mime } });
        }
        // SPA fallback — serve index.html for non-file routes
        const indexPath = join(staticDir, 'index.html');
        if (existsSync(indexPath)) {
            const content = readFileSync(indexPath);
            return c.body(content, { headers: { 'Content-Type': 'text/html' } });
        }
        return c.text('Not Found', 404);
    });
}
export function startBridgeServer(opts) {
    const app = createBridgeApp(opts.cwd);
    const staticDir = opts.staticDir ?? resolveAppDist();
    if (staticDir) {
        serveStatic(app, staticDir);
    }
    try {
        touchWorkspace(opts.cwd);
    }
    catch {
        /* non-critical */
    }
    const server = serve({ fetch: app.fetch, port: opts.port, hostname: opts.hostname ?? '127.0.0.1' });
    return { close: () => server.close() };
}
//# sourceMappingURL=index.js.map