/**
 * arcrun WASM 零件 Worker (kbdb_upsert_block)
 * POST / → JSON input → WASM (WASI preview1) → JSON output
 * SDD: polaris/mira/.agents/specs/mira-app/design.md §3.5.12.4.1
 *      matrix/arcrun/.agents/specs/arcrun/arcrun.md 三-B 新零件加入紀錄
 */

import componentWasm from '../component.wasm' assert { type: 'webassembly' };
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { createWasiShim, type WasiHostFunctions } from '../../../cypher-executor/src/lib/wasi-shim';

const app = new Hono();
app.use('*', cors());

app.get('/', (c) => c.json({ ok: true, component: 'kbdb_upsert_block' }));

app.post('/', async (c) => {
  let input: unknown;
  try {
    input = await c.req.json();
  } catch {
    return c.json({ success: false, error: 'request body must be JSON' }, 400);
  }

  try {
    const result = await runWasm(input);
    return c.json(result);
  } catch (e) {
    return c.json(
      { success: false, error: e instanceof Error ? e.message : String(e) },
      500,
    );
  }
});

export default app;

async function runWasm(input: unknown): Promise<unknown> {
  const hostFunctions: WasiHostFunctions = {
    http_request: async (url, method, headersJson, body) => {
      const headers: Record<string, string> = {};
      if (headersJson) {
        try {
          const parsed = JSON.parse(headersJson);
          if (parsed && typeof parsed === 'object') {
            for (const [k, v] of Object.entries(parsed as Record<string, unknown>)) {
              if (typeof v === 'string') headers[k] = v;
            }
          }
        } catch {}
      }
      const init: RequestInit = { method, headers };
      if (body && method.toUpperCase() !== 'GET' && method.toUpperCase() !== 'HEAD') {
        init.body = body;
      }
      const res = await fetch(url, init);
      const text = await res.text();
      // 修架構債（同 http_request）：非 2xx 包成帶 "error" key 的 envelope，
      // 讓 WASM 端既有的 error 判定正確識別失敗（原本只回 body 丟掉 status → 4xx 被判 success）。
      if (!res.ok) {
        return JSON.stringify({ error: `HTTP ${res.status}`, status: res.status, body: text });
      }
      return text;
    },
  };

  const shim = createWasiShim(JSON.stringify(input), hostFunctions);
  const instance = await WebAssembly.instantiate(
    componentWasm as WebAssembly.Module,
    shim.imports,
  );
  shim.setMemory(instance.exports.memory as WebAssembly.Memory);
  await shim.run(instance);

  const stdout = shim.getStdout().trim();
  const stderr = shim.getStderr().trim();
  if (stderr) console.error('[kbdb_upsert_block wasm stderr]', stderr);
  if (!stdout) throw new Error('WASM component produced no output');
  return JSON.parse(stdout);
}
