#!/usr/bin/env node
'use strict';

const https = require('https');

const API_KEY = process.env.Z_AI_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN;
const MODEL = 'GLM-4.6';

if (!API_KEY || API_KEY === 'your-api-key-here') {
  console.error('[ERROR] Z.AI API key not found');
  console.error('[INFO] Set Z_AI_API_KEY or ANTHROPIC_AUTH_TOKEN environment variable');
  console.error('[INFO] Example: export Z_AI_API_KEY=your-key-here');
  process.exit(1);
}

// Test request with reasoning
const requestBody = JSON.stringify({
  model: MODEL,
  messages: [
    {
      role: 'user',
      content: 'Solve this math problem step by step: What is 27 * 453? Show your reasoning process.'
    }
  ],
  stream: true,
  reasoning: true,
  reasoning_effort: 'medium',
  max_tokens: 4096,
  do_sample: true
});

const options = {
  hostname: 'api.z.ai',
  port: 443,
  path: '/api/coding/paas/v4/chat/completions',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Length': Buffer.byteLength(requestBody),
    'User-Agent': 'CCS-GLMT-StreamingTest/1.0'
  }
};

console.log('═══════════════════════════════════════════════════════════════');
console.log('Z.AI STREAMING BEHAVIOR TEST');
console.log('═══════════════════════════════════════════════════════════════');
console.log('[TEST] Initiating streaming request to Z.AI');
console.log('[TEST] Model:', MODEL);
console.log('[TEST] Stream: true');
console.log('[TEST] Reasoning: true');
console.log('[TEST] Reasoning Effort: medium');
console.log('[TEST] API Key:', API_KEY.substring(0, 10) + '...');
console.log('');

const startTime = Date.now();
let firstByteTime = null;

const req = https.request(options, (res) => {
  console.log('[HTTP] Status:', res.statusCode);
  console.log('[HTTP] Content-Type:', res.headers['content-type']);
  console.log('');

  if (res.statusCode !== 200) {
    let errorBody = '';
    res.on('data', chunk => errorBody += chunk);
    res.on('end', () => {
      console.error('[ERROR] Request failed:', res.statusCode, res.statusMessage);
      console.error('[ERROR] Response:', errorBody);
      process.exit(1);
    });
    return;
  }

  console.log('═══════════════════════════════════════════════════════════════');
  console.log('SSE EVENTS (analyzing streaming behavior)');
  console.log('═══════════════════════════════════════════════════════════════');
  console.log('');

  let buffer = '';
  let eventCount = 0;
  let reasoningEventCount = 0;
  let reasoningInDelta = false;
  let reasoningInMessage = false;
  let totalReasoningChunks = [];
  let textEventCount = 0;

  res.on('data', (chunk) => {
    if (!firstByteTime) {
      firstByteTime = Date.now();
      console.log('[TIMING] Time to first byte:', firstByteTime - startTime, 'ms');
      console.log('');
    }

    buffer += chunk.toString();
    const lines = buffer.split('\n');

    // Keep incomplete line in buffer
    buffer = lines.pop() || '';

    lines.forEach(line => {
      if (line.startsWith('data: ')) {
        eventCount++;
        const data = line.substring(6);

        if (data === '[DONE]') {
          console.log(`[EVENT ${eventCount}] [DONE]`);
          console.log('');
          return;
        }

        try {
          const parsed = JSON.parse(data);
          const choice = parsed.choices?.[0];
          const delta = choice?.delta;
          const message = choice?.message;

          // Check for reasoning_content in delta
          if (delta?.reasoning_content) {
            reasoningInDelta = true;
            reasoningEventCount++;
            totalReasoningChunks.push(delta.reasoning_content);

            console.log(`[EVENT ${eventCount}] *** REASONING IN DELTA ***`);
            console.log('  Delta keys:', Object.keys(delta).join(', '));
            console.log('  Reasoning chunk length:', delta.reasoning_content.length);
            console.log('  Reasoning chunk preview:', JSON.stringify(delta.reasoning_content.substring(0, 80)));
            console.log('');
          }

          // Check for reasoning_content in message (complete)
          if (message?.reasoning_content) {
            reasoningInMessage = true;
            console.log(`[EVENT ${eventCount}] *** REASONING IN MESSAGE (COMPLETE) ***`);
            console.log('  Message keys:', Object.keys(message).join(', '));
            console.log('  Reasoning total length:', message.reasoning_content.length);
            console.log('  Reasoning preview:', message.reasoning_content.substring(0, 100).replace(/\n/g, ' '));
            console.log('');
          }

          // Check for text content in delta
          if (delta?.content) {
            textEventCount++;
            if (textEventCount <= 3 || eventCount % 10 === 0) {
              console.log(`[EVENT ${eventCount}] Text delta`);
              console.log('  Content:', JSON.stringify(delta.content));
              console.log('');
            }
          }

          // Show finish_reason
          if (choice?.finish_reason) {
            console.log(`[EVENT ${eventCount}] Finish reason: ${choice.finish_reason}`);
            console.log('');
          }

          // Show usage stats
          if (parsed.usage) {
            console.log(`[EVENT ${eventCount}] Usage:`, JSON.stringify(parsed.usage));
            console.log('');
          }

        } catch (e) {
          console.log(`[EVENT ${eventCount}] [PARSE ERROR]`, e.message);
          console.log('  Raw:', data.substring(0, 100));
          console.log('');
        }
      }
    });
  });

  res.on('end', () => {
    const totalTime = Date.now() - startTime;

    console.log('═══════════════════════════════════════════════════════════════');
    console.log('TEST RESULTS');
    console.log('═══════════════════════════════════════════════════════════════');
    console.log('');
    console.log('[TIMING]');
    console.log('  Time to first byte:', firstByteTime - startTime, 'ms');
    console.log('  Total duration:', totalTime, 'ms');
    console.log('');
    console.log('[EVENTS]');
    console.log('  Total events:', eventCount);
    console.log('  Text content events:', textEventCount);
    console.log('  Reasoning events:', reasoningEventCount);
    console.log('');
    console.log('[REASONING BEHAVIOR]');
    console.log('  Reasoning in delta (incremental):', reasoningInDelta);
    console.log('  Reasoning in message (complete):', reasoningInMessage);
    if (totalReasoningChunks.length > 0) {
      const totalReasoningLength = totalReasoningChunks.join('').length;
      console.log('  Total reasoning chunks:', totalReasoningChunks.length);
      console.log('  Total reasoning length:', totalReasoningLength);
    }
    console.log('');
    console.log('═══════════════════════════════════════════════════════════════');
    console.log('SCENARIO DETERMINATION');
    console.log('═══════════════════════════════════════════════════════════════');

    if (reasoningInDelta) {
      console.log('');
      console.log('[✓] SCENARIO A: Incremental Streaming');
      console.log('    reasoning_content appears in delta objects');
      console.log('    Multiple events contain reasoning chunks');
      console.log('    RECOMMENDATION: Proceed with full streaming implementation');
    } else if (reasoningInMessage) {
      console.log('');
      console.log('[!] SCENARIO B: Complete at End');
      console.log('    reasoning_content only in final message object');
      console.log('    No intermediate reasoning chunks');
      console.log('    RECOMMENDATION: Hybrid streaming (text streams, reasoning buffered)');
    } else {
      console.log('');
      console.log('[X] SCENARIO C: No Streaming Support');
      console.log('    No reasoning_content in streaming mode');
      console.log('    RECOMMENDATION: Keep buffered mode only');
    }
    console.log('');
    console.log('═══════════════════════════════════════════════════════════════');
  });
});

req.on('error', (error) => {
  console.error('[ERROR]', error.message);
  process.exit(1);
});

req.write(requestBody);
req.end();
