import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { DatabaseSync } from 'node:sqlite';
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');

import {
  createVacuumBackup,
  inspectDatabaseFile,
  quarantineDatabaseFiles
} from '../src/database-health.js';

test('database health, verified backup and corruption quarantine', () => {
  const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'onlycoin-db-health-'));
  try {
    const dbPath = path.join(tempDir, 'onlycoin.db');
    assert.equal(inspectDatabaseFile(dbPath).status, 'missing');

    const db = new DatabaseSync(dbPath);
    db.exec('CREATE TABLE demo(id INTEGER PRIMARY KEY, value TEXT NOT NULL);');
    db.prepare('INSERT INTO demo(value) VALUES(?)').run('ok');
    db.close();

    const healthy = inspectDatabaseFile(dbPath, { full: true });
    assert.equal(healthy.status, 'healthy');
    assert.deepEqual(healthy.results, ['ok']);

    const backupPath = path.join(tempDir, 'backups', 'onlycoin-backup.db');
    const backup = createVacuumBackup(dbPath, backupPath);
    assert.equal(backup.health.status, 'healthy');
    assert.equal(inspectDatabaseFile(backupPath, { full: true }).status, 'healthy');

    const scripted = spawnSync(process.execPath, ['scripts/backup-database.js'], {
      cwd: rootDir,
      env: { ...process.env, DATA_DIR: tempDir, NODE_ENV: 'development' },
      encoding: 'utf8'
    });
    assert.equal(scripted.status, 0, scripted.stderr || scripted.stdout);
    const scriptedBackups = fs.readdirSync(path.join(tempDir, 'backups')).filter((name) => /^onlycoin-.*\.db$/.test(name));
    assert.ok(scriptedBackups.length >= 1);

    fs.writeFileSync(`${dbPath}-wal`, 'sidecar-test');
    fs.writeFileSync(`${dbPath}-shm`, 'sidecar-test');
    fs.writeFileSync(dbPath, Buffer.from('this is not a sqlite database'));

    const corrupt = inspectDatabaseFile(dbPath, { full: true });
    assert.equal(corrupt.status, 'corrupt');

    const quarantine = quarantineDatabaseFiles(dbPath, {
      reason: 'automated corruption test',
      recoveryRoot: path.join(tempDir, 'recovery'),
      now: new Date('2026-07-29T12:34:56.000Z')
    });
    assert.equal(fs.existsSync(dbPath), false);
    assert.equal(fs.existsSync(`${dbPath}-wal`), false);
    assert.equal(fs.existsSync(`${dbPath}-shm`), false);
    assert.equal(fs.existsSync(path.join(quarantine.targetDir, 'onlycoin.db')), true);
    assert.equal(fs.existsSync(path.join(quarantine.targetDir, 'onlycoin.db-wal')), true);
    assert.equal(fs.existsSync(path.join(quarantine.targetDir, 'onlycoin.db-shm')), true);
    assert.equal(fs.existsSync(path.join(quarantine.targetDir, 'recovery-manifest.json')), true);
  } finally {
    fs.rmSync(tempDir, { recursive: true, force: true });
  }
});
