import { spawnSync } from 'node:child_process';
import { mkdtempSync, writeFileSync, existsSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';

const root = resolve(import.meta.dirname, '..');

function runScript(script, args) {
  return spawnSync(process.execPath, [join(root, script), ...args], {
    cwd: root,
    encoding: 'utf8',
  });
}

describe('production ops scripts', () => {
  it('prints a pg_dump command in dry-run mode without writing the target file', () => {
    const dir = mkdtempSync(join(tmpdir(), 'ftb-pg-backup-'));
    const output = join(dir, 'backup.dump');

    const result = runScript('scripts/backup-postgres.mjs', [
      '--dry-run',
      '--env-file',
      '.env.production.example',
      '--output',
      output,
    ]);

    assert.equal(result.status, 0, result.stderr);
    assert.match(result.stdout, /docker compose/);
    assert.match(result.stdout, /pg_dump/);
    assert.match(result.stdout, /backup\.dump/);
    assert.equal(existsSync(output), false);
  });

  it('refuses restore by default unless --confirm-overwrite is supplied', () => {
    const dir = mkdtempSync(join(tmpdir(), 'ftb-pg-restore-'));
    const input = join(dir, 'backup.dump');
    writeFileSync(input, 'not-a-real-dump');

    const result = runScript('scripts/restore-postgres.mjs', [
      '--env-file',
      '.env.production.example',
      '--input',
      input,
    ]);

    assert.notEqual(result.status, 0);
    assert.match(result.stderr, /--confirm-overwrite/);
  });

  it('prints fresh database restore steps in dry-run mode after explicit overwrite confirmation', () => {
    const dir = mkdtempSync(join(tmpdir(), 'ftb-pg-restore-dry-'));
    const input = join(dir, 'backup.dump');
    writeFileSync(input, 'not-a-real-dump');

    const result = runScript('scripts/restore-postgres.mjs', [
      '--dry-run',
      '--confirm-overwrite',
      '--env-file',
      '.env.production.example',
      '--input',
      input,
    ]);

    assert.equal(result.status, 0, result.stderr);
    assert.match(result.stdout, /dropdb/);
    assert.match(result.stdout, /createdb/);
    assert.match(result.stdout, /pg_restore/);
  });

  it('prints a server_data volume tar backup command in dry-run mode', () => {
    const result = runScript('scripts/backup-server-data.mjs', [
      '--dry-run',
      '--env-file',
      '.env.production.example',
    ]);

    assert.equal(result.status, 0, result.stderr);
    assert.match(result.stdout, /docker run/);
    assert.match(result.stdout, /ftb_pm_server_data/);
    assert.match(result.stdout, /tar -czf/);
  });
});
