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 !== `ARCHIVE ${nodeName} DIRECT CONTROL EVIDENCE`) {
  throw new Error('Exact validator name and direct-control evidence confirmation are required.');
}
const approval = JSON.parse(fs.readFileSync(service.paths.approvalPath, 'utf8'));
const topologyBytes = fs.readFileSync(service.paths.topologyPath);
const topology = JSON.parse(topologyBytes);
const topologySha256 = crypto.createHash('sha256').update(topologyBytes).digest('hex');
const now = Date.now();
if (approval.action !== 'ATTEST_EXISTING_SINGLE_VALIDATOR_DIRECT_LAN'
  || approval.nodeName !== nodeName
  || approval.topologySha256 !== topologySha256
  || approval.controls?.directLanQuorumAttestation !== true
  || approval.controls?.validatorProcessRestartAllowed !== false
  || new Date(approval.approvedAt || 0).getTime() > now
  || new Date(approval.expiresAt || 0).getTime() <= now) {
  throw new Error('The active single-validator read-only attestation approval is invalid or expired.');
}
const target = topology.validators.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 || {};
if (node?.clientVersion !== '1.4.123-validator-direct-control-heartbeat-diagnostic-tunnel-fallback-locked'
  || node?.status !== 'active'
  || now - new Date(node.lastHeartbeatAt || 0).getTime() > 3 * 60_000
  || meta.validatorRuntimeState !== 'validator-active'
  || Number(meta.validatorRuntimeProcessPid || 0) <= 0
  || Number(meta.validatorRuntimePeerCount || 0) < 2
  || Number(meta.validatorRuntimeBlockNumber || 0) <= 0) {
  throw new Error('Fresh v123 validator runtime evidence is incomplete.');
}
const aisforLogPath = 'C:\\Users\\Administrator\\.pm2\\logs\\aisfor-out.log';
const logStat = fs.statSync(aisforLogPath);
if (logStat.mtimeMs < new Date(approval.approvedAt).getTime()) {
  throw new Error('AISFOR audit log predates the active approval.');
}
const bytesToRead = Math.min(logStat.size, 2 * 1024 * 1024);
const fd = fs.openSync(aisforLogPath, 'r');
const buffer = Buffer.alloc(bytesToRead);
try { fs.readSync(fd, buffer, 0, bytesToRead, logStat.size - bytesToRead); } finally { fs.closeSync(fd); }
const logTail = buffer.toString('utf8');
const expectedOffer = `[VALIDATOR_TUNNEL_OFFER] direct-attestation node=${nodeName} approval=${approval.approvalId}`;
const expectedHeartbeat = `[VALIDATOR_TUNNEL_HEARTBEAT] node=${target.pcName} [direct-control] managerState=applied runtimeState=validator-active directStatic=true processRunning=true approval=${approval.approvalId}`;
if (!logTail.includes(expectedOffer) || !logTail.includes(expectedHeartbeat)) {
  throw new Error('Bound direct offer and authenticated direct-control heartbeat evidence were not both found.');
}
const historyRoot = path.join(path.dirname(service.paths.approvalPath), 'approval-history');
fs.mkdirSync(historyRoot, { recursive: true });
const archivePath = path.join(historyRoot, `${approval.approvalId}-direct-control-attested.json`);
if (fs.existsSync(archivePath)) throw new Error('Direct-control evidence archive already exists.');
const archivedAt = new Date();
const archived = {
  ...approval,
  archiveStatus: 'DIRECT_CONTROL_ATTESTED',
  evidence: {
    schemaVersion: 'plais-validator-direct-control-evidence/v1',
    nodeName,
    pcName: target.pcName,
    clientVersion: node.clientVersion,
    processPid: Number(meta.validatorRuntimeProcessPid),
    blockNumber: Number(meta.validatorRuntimeBlockNumber),
    peerCount: Number(meta.validatorRuntimePeerCount),
    managerState: 'applied',
    runtimeState: 'validator-active',
    directStatic: true,
    processRunning: true,
    offerAuditObserved: true,
    authenticatedHeartbeatObserved: true,
    topologySha256,
    observedAt: archivedAt.toISOString()
  },
  archivedAt: archivedAt.toISOString()
};
fs.writeFileSync(archivePath, `${JSON.stringify(archived, null, 2)}\n`, { encoding: 'utf8', flag: 'wx' });
fs.unlinkSync(service.paths.approvalPath);
console.log(JSON.stringify({ ok: true, status: archived.archiveStatus, approvalId: approval.approvalId,
  nodeName, processPid: archived.evidence.processPid, blockNumber: archived.evidence.blockNumber,
  peerCount: archived.evidence.peerCount, archivePath }, null, 2));
