// src/backends/claude/tool-bridge.ts
var TOOL_BRIDGE_DIR = "/tmp/tool-bridge";
var TOOL_BRIDGE_SCRIPT_PATH = `${TOOL_BRIDGE_DIR}/bridge.sh`;
var TOOL_BRIDGE_TOOLS_PATH = `${TOOL_BRIDGE_DIR}/tools.json`;
var TOOL_BRIDGE_REQUEST_PATH = `${TOOL_BRIDGE_DIR}/request.json`;
var TOOL_BRIDGE_RESPONSE_PATH = `${TOOL_BRIDGE_DIR}/response.json`;
var TOOL_BRIDGE_PENDING_PATH = `${TOOL_BRIDGE_DIR}/pending`;
var TOOL_BRIDGE_MCP_CONFIG_PATH = `${TOOL_BRIDGE_DIR}/mcp-config.json`;
function generateBridgeScript() {
  return `#!/bin/bash
# Auto-generated MCP stdio server for custom tool bridge.
# Pure bash \u2014 no Node.js dependency. Instant startup on Firecracker VMs.

TOOLS_PATH="${TOOL_BRIDGE_TOOLS_PATH}"
REQUEST_PATH="${TOOL_BRIDGE_REQUEST_PATH}"
RESPONSE_PATH="${TOOL_BRIDGE_RESPONSE_PATH}"
PENDING_PATH="${TOOL_BRIDGE_PENDING_PATH}"

send_response() {
  printf '%s\\n' "$1"
}

TOOLS_LIST_JSON=""
if [ -f "$TOOLS_PATH" ]; then
  TOOLS_LIST_JSON=$(sed 's/input_schema/inputSchema/g' "$TOOLS_PATH")
fi

handle_request() {
  local body="$1"
  local method id
  method=$(echo "$body" | grep -o '"method":"[^"]*"' | head -1 | cut -d'"' -f4)
  id=$(echo "$body" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)

  case "$method" in
    initialize)
      # Echo the client's protocolVersion if present (MCP spec: server
      # should respond with the negotiated/supported version). Falls back
      # to 2024-11-05 which is what claude code 2.x expects -- responding
      # with a newer version like 2025-11-25 causes claude to silently
      # drop the server's tools from its registry, surfacing as
      # "No such tool available" errors on the first turn even though
      # the bridge responded successfully.
      client_pv=$(echo "$body" | grep -oE '"protocolVersion":"[^"]+"' | head -1 | cut -d'"' -f4)
      [ -z "$client_pv" ] && client_pv="2024-11-05"
      send_response '{"jsonrpc":"2.0","id":'"$id"',"result":{"protocolVersion":"'"$client_pv"'","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"tool-bridge","version":"1.0.0"}}}'
      ;;
    notifications/*) ;;
    ping)
      [ -n "$id" ] && send_response '{"jsonrpc":"2.0","id":'"$id"',"result":{}}'
      ;;
    tools/list)
      send_response '{"jsonrpc":"2.0","id":'"$id"',"result":{"tools":'"$TOOLS_LIST_JSON"'}}'
      ;;
    tools/call)
      local tool_name
      # Extract tool name from params.name (NOT from any nested
      # arguments.name field). Body shape:
      #   {..., "params":{"name":"<TOOL>","arguments":{...}}}
      # Tools whose input schema includes a "name" property (e.g. our
      # propose_name with input { name: "..." }) would otherwise have
      # the argument value mis-extracted by a plain grep | tail -1.
      # Anchor on the "params":{ opener so we only match the "name":
      # field immediately after it.
      tool_name=$(echo "$body" | grep -oE '"params":\\{"name":"[^"]+"' | head -1 | sed 's/.*"name":"//;s/"$//')
      if [ -z "$tool_name" ]; then
        # Fallback: first "name":"..." in the body (params may have
        # been pretty-printed or contain whitespace between { and "name").
        tool_name=$(echo "$body" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
      fi

      # Reject unknown tools immediately (don't wait for gateway response)
      if [ -n "$TOOLS_LIST_JSON" ]; then
        if ! echo "$TOOLS_LIST_JSON" | grep -q "\\"$tool_name\\""; then
          send_response '{"jsonrpc":"2.0","id":'"$id"',"result":{"content":[{"type":"text","text":"Unknown tool: '"$tool_name"'"}],"isError":true}}'
          return
        fi
      fi

      # Replay case: response.json already exists (--resume re-entry)
      if [ -f "$RESPONSE_PATH" ]; then
        local rdata
        rdata=$(cat "$RESPONSE_PATH" | tr -d '\\n' | sed 's/\\\\/\\\\\\\\/g; s/"/\\\\"/g')
        rm -f "$RESPONSE_PATH"
        send_response '{"jsonrpc":"2.0","id":'"$id"',"result":{"content":[{"type":"text","text":"'"$rdata"'"}],"isError":false}}'
        return
      fi

      # Write the full MCP request body to request.json.
      # The driver parses tool_use_id, name, and input from it.
      # Previous approach used grep to extract arguments, which broke on
      # nested JSON objects (truncated at first closing brace).
      printf '%s' "$body" > "$REQUEST_PATH"
      touch "$PENDING_PATH"

      # Poll for response.json (200ms interval, 5min timeout)
      local elapsed=0
      while [ $elapsed -lt 1500 ]; do
        if [ -f "$RESPONSE_PATH" ]; then
          local rdata
          rdata=$(cat "$RESPONSE_PATH" | tr -d '\\n' | sed 's/\\\\/\\\\\\\\/g; s/"/\\\\"/g')
          rm -f "$RESPONSE_PATH" "$PENDING_PATH"
          send_response '{"jsonrpc":"2.0","id":'"$id"',"result":{"content":[{"type":"text","text":"'"$rdata"'"}],"isError":false}}'
          return
        fi
        sleep 0.2
        elapsed=$((elapsed + 1))
      done
      # Timeout
      rm -f "$PENDING_PATH"
      send_response '{"jsonrpc":"2.0","id":'"$id"',"error":{"code":-32603,"message":"Timeout waiting for tool response"}}'
      ;;
    *)
      [ -n "$id" ] && send_response '{"jsonrpc":"2.0","id":'"$id"',"error":{"code":-32601,"message":"Method not found"}}'
      ;;
  esac
}

# Main loop: handle both raw JSON lines and Content-Length framed messages
while IFS= read -r line; do
  line=\${line%$'\\r'}
  [ -z "$line" ] && continue
  case "$line" in
    Content-Length:*)
      while IFS= read -r hdr; do hdr=\${hdr%$'\\r'}; [ -z "$hdr" ] && break; done
      body=$(head -c "\${line#Content-Length: }")
      handle_request "$body" ;;
    "{"*) handle_request "$line" ;;
  esac
done
`;
}
function buildBridgeMcpConfig(existingServers) {
  return {
    ...existingServers,
    "tool-bridge": {
      command: "bash",
      args: [TOOL_BRIDGE_SCRIPT_PATH]
    }
  };
}
function buildBridgeMcpConfigFile() {
  return JSON.stringify({
    mcpServers: {
      "tool-bridge": {
        command: "bash",
        args: [TOOL_BRIDGE_SCRIPT_PATH]
      }
    }
  });
}
function toolsToJson(tools) {
  return JSON.stringify(
    tools.map((t) => ({
      name: t.name,
      description: t.description,
      input_schema: t.input_schema
    }))
  );
}

export {
  TOOL_BRIDGE_DIR,
  TOOL_BRIDGE_SCRIPT_PATH,
  TOOL_BRIDGE_TOOLS_PATH,
  TOOL_BRIDGE_REQUEST_PATH,
  TOOL_BRIDGE_RESPONSE_PATH,
  TOOL_BRIDGE_PENDING_PATH,
  TOOL_BRIDGE_MCP_CONFIG_PATH,
  generateBridgeScript,
  buildBridgeMcpConfig,
  buildBridgeMcpConfigFile,
  toolsToJson
};
