import { WorkflowExecutor } from './src/vl/workflow-executor.js';

let passed = 0;
let failed = 0;

function test(name, fn) {
  return Promise.resolve()
    .then(fn)
    .then(() => {
      console.log(`  ✓ ${name}`);
      passed++;
    })
    .catch((err) => {
      console.log(`  ✗ ${name}: ${err.message}`);
      failed++;
    });
}

function assert(cond, msg) {
  if (!cond) throw new Error(msg || 'Assertion failed');
}

console.log('\n── Workflow JSON Guard Regression ──');

function createExecutorWithResponse(text) {
  const executor = new WorkflowExecutor({ workDir: '/tmp/vlcode-json-guard', model: 'claude-opus-4-6' });
  executor.client = {
    messages: {
      async create() {
        return {
          content: [{ type: 'text', text }],
          stop_reason: 'end_turn',
          usage: {},
          model: 'stub-model',
        };
      },
    },
  };
  return executor;
}

await test('critical PRD generation rejects empty JSON output', async () => {
  const executor = createExecutorWithResponse('{}');
  let threw = false;

  try {
    await executor._buildLLMAdapter().call({
      docs: ['31'],
      output_config: { format: { type: 'json_object' } },
      messages: [{ role: 'user', content: 'Requirement: test' }],
    });
  } catch (err) {
    threw = true;
    assert(err.message.includes('Critical workflow JSON step'), `unexpected error: ${err.message}`);
  }

  assert(threw, 'expected critical JSON step to throw');
});

await test('non-critical JSON steps still fall back to empty object for compatibility', async () => {
  const executor = createExecutorWithResponse('No JSON here.');
  const result = await executor._buildLLMAdapter().call({
    docs: ['999'],
    output_config: { format: { type: 'json_object' } },
    messages: [{ role: 'user', content: 'test' }],
  });

  assert(result.content === '{}', `expected compatibility fallback, got ${result.content}`);
});

await test('JSON repair removes superfluous closing braces from near-valid payloads', async () => {
  const malformed = '{"apps":[{"id":"Main"}],"sections":[{"id":"Home","internal":{"blocks":[]}}}],"components":[]}';
  const executor = createExecutorWithResponse(malformed);
  const result = await executor._buildLLMAdapter().call({
    docs: ['999'],
    output_config: { format: { type: 'json_object' } },
    messages: [{ role: 'user', content: 'test' }],
  });

  const parsed = JSON.parse(result.content);
  assert(Array.isArray(parsed.apps), 'apps should be preserved after repair');
  assert(Array.isArray(parsed.sections), 'sections should be preserved after repair');
});

console.log(`\n── Results ──\n\n  ${passed} passed, ${failed} failed\n`);
process.exit(failed > 0 ? 1 : 0);
