/**
 * Test for completion detection via readSignalCompletion
 */

import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest';
import { mkdtemp, writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { rmSync } from 'node:fs';
import { OutputHandler } from './output-handler.js';
import type { AgentRepository } from '../db/repositories/agent-repository.js';

describe('Completion Detection Fix', () => {
  let tempDir: string;
  let outputHandler: OutputHandler;
  let mockAgentRepo: AgentRepository;

  beforeEach(async () => {
    tempDir = await mkdtemp(join(tmpdir(), 'completion-test-'));

    // Mock repositories
    mockAgentRepo = {
      update: vi.fn(),
      findById: vi.fn().mockResolvedValue({ id: 'test-agent', mode: 'refine' }),
    } as any;

    outputHandler = new OutputHandler(mockAgentRepo);
  });

  afterEach(() => {
    rmSync(tempDir, { recursive: true, force: true });
  });

  test('detects completion from signal.json with "questions" status', async () => {
    const agentWorkdir = join(tempDir, 'test-agent');
    const cwDir = join(agentWorkdir, '.cw/output');
    await mkdir(cwDir, { recursive: true });

    const signalContent = JSON.stringify({
      status: 'questions',
      questions: [{ id: 'q1', text: 'Do you want to proceed?' }]
    });
    await writeFile(join(cwDir, 'signal.json'), signalContent);

    const readSignalCompletion = (outputHandler as any).readSignalCompletion.bind(outputHandler);
    const result = await readSignalCompletion(agentWorkdir);

    expect(result).not.toBeNull();
    expect(JSON.parse(result).status).toBe('questions');
  });

  test('detects completion from signal.json with "done" status', async () => {
    const agentWorkdir = join(tempDir, 'test-agent');
    const cwDir = join(agentWorkdir, '.cw/output');
    await mkdir(cwDir, { recursive: true });

    const signalContent = JSON.stringify({
      status: 'done',
      result: 'Task completed successfully'
    });
    await writeFile(join(cwDir, 'signal.json'), signalContent);

    const readSignalCompletion = (outputHandler as any).readSignalCompletion.bind(outputHandler);
    const result = await readSignalCompletion(agentWorkdir);

    expect(result).not.toBeNull();
    expect(JSON.parse(result).status).toBe('done');
  });

  test('detects completion from signal.json with "error" status', async () => {
    const agentWorkdir = join(tempDir, 'test-agent');
    const cwDir = join(agentWorkdir, '.cw/output');
    await mkdir(cwDir, { recursive: true });

    const signalContent = JSON.stringify({
      status: 'error',
      error: 'Something went wrong'
    });
    await writeFile(join(cwDir, 'signal.json'), signalContent);

    const readSignalCompletion = (outputHandler as any).readSignalCompletion.bind(outputHandler);
    const result = await readSignalCompletion(agentWorkdir);

    expect(result).not.toBeNull();
    expect(JSON.parse(result).status).toBe('error');
  });

  test('returns null when signal.json does not exist', async () => {
    const agentWorkdir = join(tempDir, 'test-agent');

    const readSignalCompletion = (outputHandler as any).readSignalCompletion.bind(outputHandler);
    const result = await readSignalCompletion(agentWorkdir);

    expect(result).toBeNull();
  });

  test('returns null for incomplete status', async () => {
    const agentWorkdir = join(tempDir, 'test-agent');
    const cwDir = join(agentWorkdir, '.cw/output');
    await mkdir(cwDir, { recursive: true });

    const signalContent = JSON.stringify({
      status: 'running',
      progress: 'Still working...'
    });
    await writeFile(join(cwDir, 'signal.json'), signalContent);

    const readSignalCompletion = (outputHandler as any).readSignalCompletion.bind(outputHandler);
    const result = await readSignalCompletion(agentWorkdir);

    expect(result).toBeNull();
  });

  test('handles malformed signal.json gracefully', async () => {
    const agentWorkdir = join(tempDir, 'test-agent');
    const cwDir = join(agentWorkdir, '.cw/output');
    await mkdir(cwDir, { recursive: true });

    await writeFile(join(cwDir, 'signal.json'), '{ invalid json }');

    const readSignalCompletion = (outputHandler as any).readSignalCompletion.bind(outputHandler);
    const result = await readSignalCompletion(agentWorkdir);

    expect(result).toBeNull();
  });
});
