import { test, expect } from 'vitest';
import { promises as fs } from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import { computeHashesFromStream } from '../../src/services/checksumService';
import { streamArchiveEntry } from '../../src/services/archiveReader';
import { createHash } from 'crypto';

function hasBinary(bin: string): boolean {
  try {
    execSync(`which ${bin}`, { stdio: 'ignore' });
    return true;
  } catch (e) {
    return false;
  }
}

const wantIntegration = process.env.INTEGRATION === '1';
const canCreate = hasBinary('7z') || hasBinary('zip');

if (!wantIntegration) {
  test.skip('archiveReader integration tests require INTEGRATION=1', () => {});
} else if (!canCreate) {
  test.skip('archiveReader integration tests skipped: no archive creation tool (7z or zip) available', () => {});
} else {
  test('reads entry from zip using system tools', async () => {
    const tmpDir = await fs.mkdtemp(path.join(process.cwd(), 'tmp-arc-'));
    const inner = path.join(tmpDir, 'game.rom');
    const content = 'QUASAR-INTEGRATION-TEST';
    await fs.writeFile(inner, content);

    const archivePath = path.join(tmpDir, 'simple.zip');

    // create zip using available tool
    if (hasBinary('7z')) {
      execSync(`7z a -tzip ${JSON.stringify(archivePath)} ${JSON.stringify(inner)}`, {
        stdio: 'ignore',
      });
    } else {
      execSync(`zip -j ${JSON.stringify(archivePath)} ${JSON.stringify(inner)}`, {
        stdio: 'ignore',
      });
    }

    const stream = await streamArchiveEntry(archivePath, path.basename(inner));
    expect(stream).not.toBeNull();
    const hashes = await computeHashesFromStream(stream as any);

    const expectedMd5 = createHash('md5').update(content).digest('hex');
    expect(hashes.md5).toBe(expectedMd5);

    await fs.rm(tmpDir, { recursive: true, force: true });
  });
}
