import assert from 'node:assert/strict'
import test from 'node:test'

import { consumeSkillRunStream } from './skillRunStream.js'

function streamResponse(chunks) {
  const encoder = new TextEncoder()
  return new Response(new ReadableStream({
    start(controller) {
      for (const chunk of chunks) controller.enqueue(encoder.encode(chunk))
      controller.close()
    },
  }), {
    status: 200,
    headers: { 'Content-Type': 'text/event-stream' },
  })
}

test('consumeSkillRunStream reports heartbeat, resume and done events', async () => {
  const seen = []
  const eventIds = []
  const res = streamResponse([
    'id: 1\n',
    'data: {"t":"session","sessionId":"sid_1"}\n\n',
    'id: 2\n',
    'data: {"t":"heartbeat","sessionId":"sid_1","state":"running","eventId":2}\n\n',
    'id: 3\n',
    'data: {"t":"resume","sessionId":"sid_1","fromEventId":2,"replayed":1}\n\n',
    'id: 4\n',
    'data: {"t":"done","sessionId":"sid_1","state":"completed"}\n\n',
    'data: [DONE]\n\n',
  ])

  await consumeSkillRunStream(res, {
    onEvent: (evt) => eventIds.push(evt.eventId),
    onSession: (sid) => seen.push(['session', sid]),
    onHeartbeat: (evt) => seen.push(['heartbeat', evt.state, evt.eventId]),
    onResume: (evt) => seen.push(['resume', evt.fromEventId, evt.replayed]),
    onDone: (evt) => seen.push(['done', evt.state]),
  })

  assert.deepEqual(seen, [
    ['session', 'sid_1'],
    ['heartbeat', 'running', 2],
    ['resume', 2, 1],
    ['done', 'completed'],
  ])
  assert.deepEqual(eventIds, [1, 2, 3, 4])
})

test('consumeSkillRunStream dispatches status, reasoning, warning, artifact and provider session events', async () => {
  const seen = []
  const res = streamResponse([
    'data: {"t":"status","v":"正在执行"}\n\n',
    'data: {"t":"reasoning_summary","v":"先检查输入"}\n\n',
    'data: {"t":"warning","v":"可恢复告警"}\n\n',
    'data: {"t":"artifact","artifact":{"name":"RUN_RESULT.md"}}\n\n',
    'data: {"t":"provider_session","providerSessionId":"provider_1"}\n\n',
    'data: {"t":"done","state":"completed"}\n\n',
  ])

  await consumeSkillRunStream(res, {
    onStatus: event => seen.push(['status', event.v]),
    onReasoningSummary: event => seen.push(['reasoning', event.v]),
    onWarning: event => seen.push(['warning', event.v]),
    onArtifact: event => seen.push(['artifact', event.artifact.name]),
    onProviderSession: event => seen.push(['provider', event.providerSessionId]),
  })

  assert.deepEqual(seen, [
    ['status', '正在执行'],
    ['reasoning', '先检查输入'],
    ['warning', '可恢复告警'],
    ['artifact', 'RUN_RESULT.md'],
    ['provider', 'provider_1'],
  ])
})
