require('../config/loadEnv')();
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const service = require('../services/validatorTunnelTopologyService');

const nodeName = String(process.argv.find(value => value.startsWith('--node=')) || '').slice(7);
const nodes = String(process.argv.find(value => value.startsWith('--nodes=')) || '').slice(8);
const confirm = String(process.argv.find(value => value.startsWith('--confirm=')) || '').slice(10);
const coordinatedTargets = nodes ? nodes.split(',') : [];
const coordinated = JSON.stringify(coordinatedTargets) === JSON.stringify(['validator-1', 'validator-2', 'validator-3', 'validator-4']);
const single = /^validator-[1-4]$/.test(nodeName) && !nodes;
if (!single && !coordinated) throw new Error('A single validator or the exact four-validator recovery set is required.');
if (single && confirm !== `RESTART ${nodeName} WITH DIRECT TUNNEL`) throw new Error('Exact tunnel migration confirmation is required.');
if (coordinated && confirm !== 'RESTART validator-set FOR QBFT CONSENSUS RECOVERY') throw new Error('Exact coordinated consensus recovery confirmation is required.');
if (fs.existsSync(service.paths.approvalPath)) {
  const previous = JSON.parse(fs.readFileSync(service.paths.approvalPath, 'utf8'));
  const expiresAt = new Date(previous.expiresAt || 0).getTime();
  const knownAction = [
    'RESTART_SINGLE_VALIDATOR_WITH_DIRECT_TUNNEL_PEERS',
    'RESTART_VALIDATOR_SET_FOR_QBFT_CONSENSUS_RECOVERY',
    'ACTIVATE_VALIDATOR_DIRECT_LAN_QUORUM',
    'ATTEST_EXISTING_VALIDATOR_DIRECT_LAN_QUORUM'
  ].includes(previous.action);
  if (!knownAction || !Number.isFinite(expiresAt) || expiresAt > Date.now()) {
    throw new Error('Another non-expired or unrelated tunnel migration approval is present.');
  }
  const historyRoot = path.join(path.dirname(service.paths.approvalPath), 'approval-history');
  fs.mkdirSync(historyRoot, { recursive: true });
  const archivePath = path.join(historyRoot, `${previous.approvalId}-expired-status-incomplete.json`);
  if (fs.existsSync(archivePath)) throw new Error('Expired approval archive already exists.');
  fs.renameSync(service.paths.approvalPath, archivePath);
}
const approvedAt = new Date();
const topologySha256 = crypto.createHash('sha256').update(fs.readFileSync(service.paths.topologyPath)).digest('hex');
const value = {
  schemaVersion: 'plais-validator-tunnel-migration-approval/v1',
  action: coordinated ? 'RESTART_VALIDATOR_SET_FOR_QBFT_CONSENSUS_RECOVERY' : 'RESTART_SINGLE_VALIDATOR_WITH_DIRECT_TUNNEL_PEERS',
  approvalId: coordinated
    ? `validator-consensus-restart-set-${Date.now()}-${crypto.randomBytes(5).toString('hex')}`
    : `validator-tunnel-${nodeName}-${Date.now()}-${crypto.randomBytes(5).toString('hex')}`,
  ...(coordinated ? { targetNodeNames: coordinatedTargets } : { nodeName }),
  topologySha256,
  controls: {
    validatorProcessRestartAllowed: true,
    validatorKeyReadForIdentityCheckOnly: true,
    coordinatedConsensusRecovery: coordinated,
    coordinatedRestartMaxSkewSeconds: coordinated ? 180 : 0,
    validatorKeyExportAllowed: false,
    publicRpcAllowed: false,
    externalTransactionAllowed: false,
    operatorSigningAllowed: false
  },
  approvedAt: approvedAt.toISOString(),
  expiresAt: new Date(approvedAt.getTime() + 10 * 60_000).toISOString()
};
const temp = `${service.paths.approvalPath}.${process.pid}.tmp`;
fs.writeFileSync(temp, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', flag: 'wx' });
fs.renameSync(temp, service.paths.approvalPath);
console.log(JSON.stringify({ ok: true, approvalId: value.approvalId, ...(coordinated ? { targetNodeNames: coordinatedTargets } : { nodeName }), expiresAt: value.expiresAt, publicRpcAllowed: false, externalTransactionAllowed: false, operatorSigningAllowed: false }, null, 2));
