require('../config/loadEnv')();
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const persistentStore = require('../services/persistentStore');
const service = require('../services/validatorTunnelTopologyService');
const { matchesValidatorTarget } = require('../services/validatorTargetBindingService');

const nodeName = String(process.argv.find(value => value.startsWith('--node=')) || '').slice(7);
const confirm = String(process.argv.find(value => value.startsWith('--confirm=')) || '').slice(10);
if (!/^validator-[1-3]$/.test(nodeName)
  || confirm !== `ATTEST ${nodeName} EXISTING DIRECT LAN`) {
  throw new Error('Exact single-validator direct LAN attestation confirmation is required.');
}
const topology = JSON.parse(fs.readFileSync(service.paths.topologyPath, 'utf8'));
const direct = service.getDirectQuorum(topology);
if (!direct || !['STAGED', 'ACTIVE'].includes(direct.state) || !direct.targetNodeNames.includes(nodeName)) {
  throw new Error('A staged or active direct LAN quorum target 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',
    'ACTIVATE_VALIDATOR_DIRECT_LAN_QUORUM',
    'ATTEST_EXISTING_VALIDATOR_DIRECT_LAN_QUORUM',
    'ATTEST_EXISTING_SINGLE_VALIDATOR_DIRECT_LAN'
  ].includes(previous.action);
  if (!knownAction || !Number.isFinite(expiresAt) || expiresAt > Date.now()) {
    throw new Error('A non-expired or unrelated validator 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 target = direct.targets.find(row => row.nodeName === nodeName);
const node = (persistentStore.readState().nodes || []).filter(row => matchesValidatorTarget(row, target))
  .sort((a, b) => new Date(b.lastHeartbeatAt || 0) - new Date(a.lastHeartbeatAt || 0))[0];
const meta = node?.metadata || {};
const ageMs = Date.now() - new Date(node?.lastHeartbeatAt || 0).getTime();
if (node?.status !== 'active' || ageMs < 0 || ageMs > 3 * 60_000
  || ![
    '1.4.121-validator-direct-evidence-diagnostic-tunnel-fallback-locked',
    '1.4.122-validator-direct-offer-state-diagnostic-tunnel-fallback-locked',
    '1.4.123-validator-direct-control-heartbeat-diagnostic-tunnel-fallback-locked'
  ].includes(node.clientVersion)
  || meta.validatorRuntimeState !== 'validator-active'
  || Number(meta.validatorRuntimeProcessPid || 0) <= 0
  || Number(meta.validatorRuntimePeerCount || 0) < 1) {
  throw new Error(`Single-validator direct LAN attestation readiness is incomplete: ${nodeName}.`);
}
const approvedAt = new Date();
const approval = {
  schemaVersion: 'plais-validator-tunnel-migration-approval/v1',
  action: 'ATTEST_EXISTING_SINGLE_VALIDATOR_DIRECT_LAN',
  approvalId: `validator-direct-lan-attestation-${nodeName}-${Date.now()}-${crypto.randomBytes(5).toString('hex')}`,
  nodeName,
  topologySha256: crypto.createHash('sha256').update(fs.readFileSync(service.paths.topologyPath)).digest('hex'),
  controls: {
    directLanQuorumAttestation: true,
    validatorProcessRestartAllowed: false,
    validatorKeyReadForIdentityCheckOnly: true,
    validatorKeyExportAllowed: false,
    publicRpcAllowed: false,
    externalTransactionAllowed: false,
    operatorSigningAllowed: false
  },
  approvedAt: approvedAt.toISOString(),
  expiresAt: new Date(approvedAt.getTime() + 10 * 60_000).toISOString()
};
const temporaryPath = `${service.paths.approvalPath}.${process.pid}.tmp`;
fs.writeFileSync(temporaryPath, `${JSON.stringify(approval, null, 2)}\n`, { encoding: 'utf8', flag: 'wx' });
fs.renameSync(temporaryPath, service.paths.approvalPath);
console.log(JSON.stringify({
  ok: true,
  status: 'SINGLE_VALIDATOR_EXISTING_DIRECT_LAN_ATTESTATION_APPROVED_NO_RESTART',
  approvalId: approval.approvalId,
  nodeName,
  expiresAt: approval.expiresAt,
  validatorProcessRestartAllowed: false
}, null, 2));
