#!/usr/bin/env node

import assert from 'node:assert/strict'
import { createOntologyMcpServer } from '../mcp-server.mjs'

const TOKEN = 'ontology-mcp-smoke-token'
const server = createOntologyMcpServer({
  internalTokens: [TOKEN],
  allowedOrigins: [],
  maxBodyBytes: 1024 * 1024,
})

await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve))
const address = server.address()
const baseUrl = `http://127.0.0.1:${address.port}`

try {
  const health = await fetch(`${baseUrl}/healthz`)
  const healthPayload = await health.json()
  assert.equal(health.ok, true)
  assert.equal(healthPayload.ok, true)
  assert.equal(healthPayload.mcp.readOnly, true)

  const initialized = await rpc(baseUrl, TOKEN, 1, 'initialize', { protocolVersion: '2025-06-18' })
  assert.equal(initialized.result.protocolVersion, '2025-06-18')
  assert.equal(initialized.result.capabilities.tools.listChanged, false)

  const tools = await rpc(baseUrl, TOKEN, 2, 'tools/list', {})
  const toolNames = tools.result.tools.map((tool) => tool.name).sort()
  assert.deepEqual(toolNames, [
    'ontology_get_entity',
    'ontology_get_guardrails',
    'ontology_resolve_context',
    'ontology_search',
    'ontology_status',
  ])

  const search = await rpc(baseUrl, TOKEN, 3, 'tools/call', {
    name: 'ontology_search',
    arguments: { query: 'юнит гелиос', limit: 10 },
  })
  assert.equal(search.result.isError, undefined)
  assert.equal(search.result.structuredContent.query, 'юнит гелиос')
  assert.equal(search.result.structuredContent.results.some((item) => item.entity?.id === 'gelios.unit'), true)

  const entity = await rpc(baseUrl, TOKEN, 4, 'tools/call', {
    name: 'ontology_get_entity',
    arguments: { term: 'helius' },
  })
  assert.equal(entity.result.structuredContent.entity.id, 'gelios.integration')
  assert.equal(JSON.stringify(entity.result.structuredContent).includes('/Users/'), false)

  const signalState = await rpc(baseUrl, TOKEN, 41, 'tools/call', {
    name: 'ontology_get_entity',
    arguments: { entityId: 'gelios.signal_state' },
  })
  assert.equal(signalState.result.structuredContent.entity.valueContract.field, 'signal_state')
  assert.deepEqual(
    signalState.result.structuredContent.entity.valueContract.values.map((item) => item.value),
    ['active', 'inactive'],
  )

  const guardrails = await rpc(baseUrl, TOKEN, 5, 'tools/call', {
    name: 'ontology_get_guardrails',
    arguments: { entityId: 'gelios.command_dispatch' },
  })
  assert.equal(guardrails.result.structuredContent.rules.some((rule) => rule.id === 'guardrail.gelios.commands_are_red_domain'), true)

  const unauthorized = await fetch(`${baseUrl}/mcp`, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 6, method: 'tools/list', params: {} }),
  })
  assert.equal(unauthorized.status, 401)

  console.log(JSON.stringify({
    ok: true,
    checks: [
      'health',
      'mcp_initialize',
      'read_only_tool_catalog',
      'gelios_alias_resolution',
      'gelios_value_contract_visible',
      'gelios_command_guardrail_visible',
      'evidence_paths_not_exposed',
      'internal_bearer_required',
    ],
  }, null, 2))
} finally {
  await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve()))
}

async function rpc(baseUrl, token, id, method, params) {
  const response = await fetch(`${baseUrl}/mcp`, {
    method: 'POST',
    headers: {
      authorization: `Bearer ${token}`,
      'content-type': 'application/json',
      accept: 'application/json, text/event-stream',
      'mcp-protocol-version': '2025-06-18',
    },
    body: JSON.stringify({ jsonrpc: '2.0', id, method, params }),
  })
  assert.equal(response.ok, true)
  return response.json()
}
