require('../config/loadEnv')();

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const outputPath = path.join(__dirname, '..', 'runtime', 'plais-qbft-canonical-migration', 'validator-pm2-state-attestation.json');

async function main() {
  const states = {};
  const stateArgs = Object.fromEntries(process.argv.slice(2).map(value => {
    const match = String(value).match(/^--validator-([1-4])=(online|stopped)$/);
    return match ? [`plais-qbft-validator-${match[1]}`, match[2]] : ['', ''];
  }).filter(row => row[0]));
  if (Object.keys(stateArgs).length === 4) {
    for (let index = 1; index <= 4; index += 1) {
      const name = `plais-qbft-validator-${index}`;
      states[name] = { status: stateArgs[name], pid: 0 };
    }
  } else {
    const chunks = [];
    for await (const chunk of process.stdin) chunks.push(chunk);
    const apps = JSON.parse(Buffer.concat(chunks).toString('utf8'));
    if (!Array.isArray(apps)) throw new Error('PM2 jlist input is invalid.');
    for (let index = 1; index <= 4; index += 1) {
      const name = `plais-qbft-validator-${index}`;
      const app = apps.find(row => row?.name === name);
      const status = String(app?.pm2_env?.status || 'missing');
      if (!['online', 'stopped'].includes(status)) throw new Error(`Unexpected PM2 validator status: ${name}:${status}`);
      states[name] = { status, pid: Math.max(0, Number(app?.pid || 0)) };
    }
  }
  const value = {
    schemaVersion: 'plais-validator-pm2-state-attestation/v1',
    attestationId: `pm2-state-${Date.now()}-${crypto.randomBytes(6).toString('hex')}`,
    observedAt: new Date().toISOString(),
    states
  };
  const tempPath = `${outputPath}.tmp-${process.pid}`;
  fs.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', flag: 'wx' });
  fs.renameSync(tempPath, outputPath);
  console.log(JSON.stringify({ ok: true, attestationId: value.attestationId, observedAt: value.observedAt, states }));
}

main().catch(error => {
  console.error(JSON.stringify({ ok: false, error: error.message }));
  process.exit(1);
});
