import { spawn } from 'child_process';
import { join } from 'path';
import { writeFileSync, unlinkSync, existsSync } from 'fs';
import { beforeEach, afterEach, describe, it, expect } from 'vitest';

const CLI_PATH = join(__dirname, '../../bin/meld.ts');
const TEST_FILE = 'test-input.meld.md';
const TEST_OUTPUT = 'test-input.md';

describe('meld CLI', () => {
  beforeEach(() => {
    // Create a test input file
    writeFileSync(TEST_FILE, '# Test\n\n@cmd[echo "hello"]');
  });

  afterEach(() => {
    // Cleanup test files
    if (existsSync(TEST_FILE)) unlinkSync(TEST_FILE);
    if (existsSync(TEST_OUTPUT)) unlinkSync(TEST_OUTPUT);
  });

  it('should process a simple prompt script file', (done) => {
    const ps = spawn('ts-node', [CLI_PATH, TEST_FILE]);
    
    let output = '';
    ps.stdout.on('data', (data) => {
      output += data.toString();
    });

    ps.stderr.on('data', (data) => {
      console.error(`stderr: ${data}`);
    });

    ps.on('close', (code) => {
      expect(code).toBe(0);
      expect(existsSync(TEST_OUTPUT)).toBe(true);
      expect(output).toContain(`🦾 ${TEST_FILE} → ${TEST_OUTPUT}`);
      done();
    });
  });

  it('should respect --overwrite flag', (done) => {
    // First create the output file
    writeFileSync(TEST_OUTPUT, 'existing content');

    const ps = spawn('ts-node', [CLI_PATH, TEST_FILE, '--overwrite']);
    
    let output = '';
    ps.stdout.on('data', (data) => {
      output += data.toString();
    });

    ps.on('close', (code) => {
      expect(code).toBe(0);
      expect(existsSync(TEST_OUTPUT)).toBe(true);
      expect(output).toContain(`🦾 ${TEST_FILE} → ${TEST_OUTPUT}`);
      done();
    });
  });

  it('should support custom output path', (done) => {
    const customOutput = 'custom-output.md';
    const ps = spawn('ts-node', [CLI_PATH, TEST_FILE, '-o', customOutput]);
    
    let output = '';
    ps.stdout.on('data', (data) => {
      output += data.toString();
    });

    ps.on('close', (code) => {
      expect(code).toBe(0);
      expect(existsSync(customOutput)).toBe(true);
      expect(output).toContain(`🦾 ${TEST_FILE} → ${customOutput}`);
      // Cleanup custom output
      if (existsSync(customOutput)) unlinkSync(customOutput);
      done();
    });
  });

  it('should show dry-run output', (done) => {
    const ps = spawn('ts-node', [CLI_PATH, TEST_FILE, '--dry-run']);
    
    let output = '';
    ps.stdout.on('data', (data) => {
      output += data.toString();
    });

    ps.on('close', (code) => {
      expect(code).toBe(0);
      expect(output).toContain('Commands that would be executed');
      done();
    });
  });
}); 