import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';

const here = new URL('./', import.meta.url);
const record = JSON.parse(await readFile(new URL('bos-launchpad-sale.json', here), 'utf8'));

function parseDecimal(value) {
  const source = String(value);
  assert.match(source, /^\d+(?:\.\d+)?$/, `invalid unsigned decimal: ${source}`);
  const [whole, fraction = ''] = source.split('.');
  return { whole, fraction };
}

function addExact(values) {
  const parsed = values.map(parseDecimal);
  const scale = Math.max(...parsed.map(({ fraction }) => fraction.length));
  const sum = parsed.reduce((total, { whole, fraction }) => (
    total + BigInt(`${whole}${fraction.padEnd(scale, '0')}`)
  ), 0n);
  if (scale === 0) return sum.toString();
  const raw = sum.toString().padStart(scale + 1, '0');
  const whole = raw.slice(0, -scale);
  const fraction = raw.slice(-scale).replace(/0+$/, '');
  return fraction ? `${whole}.${fraction}` : whole;
}

function formatRounded(value, places) {
  const { whole, fraction } = parseDecimal(value);
  const scale = fraction.length;
  let scaled;
  if (scale <= places) {
    scaled = BigInt(`${whole}${fraction.padEnd(places, '0')}`);
  } else {
    const raw = BigInt(`${whole}${fraction}`);
    const divisor = 10n ** BigInt(scale - places);
    scaled = (raw + divisor / 2n) / divisor;
  }
  const digits = scaled.toString().padStart(places + 1, '0');
  const integer = digits.slice(0, -places).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  return places === 0 ? integer : `${integer}.${digits.slice(-places)}`;
}

function sha256(bytes) {
  return createHash('sha256').update(bytes).digest('hex');
}

assert.equal(record.metadataIndex.snapshotFile, 'bos-origins-home-2026-08-21.base64.txt');
assert.deepEqual(record.periods.map(({ snapshotFile }) => snapshotFile), [
  'bos-origins-ledger-one-2026-08-21.json',
  'bos-origins-ledger-two-2026-08-21.json'
]);
const homeSnapshotBase64 = await readFile(new URL(record.metadataIndex.snapshotFile, here), 'utf8');
const homeSnapshot = Buffer.from(homeSnapshotBase64.replace(/\s/g, ''), 'base64');
const ledgerSnapshots = (await Promise.all(record.periods.map(({ snapshotFile }) => (
  readFile(new URL(snapshotFile, here), 'utf8')
)))).map((text) => text.trimEnd());
const ledgerSnapshotRecords = ledgerSnapshots.map(JSON.parse);

assert.equal(record.researchCutoff, '2026-08-21');
assert.equal(record.periods.length, 2, 'exactly two Origins backend periods');
assert.ok(record.periods.every(({ isCompleted }) => isCompleted === true), 'both periods are completed');
assert.equal(sha256(homeSnapshot), record.metadataIndex.responseSha256, 'preserved homepage response hash');
assert.deepEqual(ledgerSnapshots.map((text) => sha256(Buffer.from(text))), record.periods.map(({ responseSha256 }) => responseSha256), 'preserved API response hashes');
const homeSnapshotText = homeSnapshot.toString('utf8');
for (const period of record.periods) {
  assert.ok(homeSnapshotText.includes(`\\\"id\\\":\\\"${period.phaseId}\\\"`), `homepage includes phase ${period.phaseId}`);
  assert.ok(homeSnapshotText.includes(`\\\"pid\\\":\\\"${period.pid}\\\"`), `homepage includes pid ${period.pid}`);
  assert.ok(homeSnapshotText.includes(`\\\"startDate\\\":\\\"${period.start}\\\"`), `homepage includes start ${period.start}`);
  assert.ok(homeSnapshotText.includes(`\\\"endDate\\\":\\\"${period.end}\\\"`), `homepage includes end ${period.end}`);
}
for (const [index, snapshot] of ledgerSnapshotRecords.entries()) {
  assert.equal(snapshot.tokensSold, record.periods[index].tokensSold, `period ${index + 1} tokensSold snapshot`);
  assert.equal(snapshot.usdCollected, record.periods[index].usdCollected, `period ${index + 1} usdCollected snapshot`);
  assert.equal(snapshot.isCompleted, true, `period ${index + 1} completed snapshot`);
}
const phaseIds = record.periods.map(({ phaseId }) => phaseId);
assert.equal(new Set(phaseIds).size, record.periods.length, 'period phase IDs are distinct');
assert.deepEqual(record.calculation.addendPhaseIds, phaseIds, 'exactly the two backend periods are calculation addends');
assert.deepEqual(record.calculation.excludedFromAddends, ['phaseOneSubset'], 'combined total uses the two completed backend-period counters');
assert.equal(record.periods[0].end, record.periods[1].start, 'periods are contiguous');
assert.ok(Date.parse(record.periods[0].start) < Date.parse(record.periods[0].end), 'first period is ordered');
assert.ok(Date.parse(record.periods[1].start) < Date.parse(record.periods[1].end), 'second period is ordered');
assert.equal(addExact(record.periods.map(({ tokensSold }) => tokensSold)), record.combined.tokensSold);
assert.equal(addExact(record.periods.map(({ usdCollected }) => usdCollected)), record.combined.usdCollected);
assert.equal(`${formatRounded(record.combined.tokensSold, 2)} BOS`, record.combined.displayTokens, 'reader-facing BOS total');
assert.equal(`$${formatRounded(record.combined.usdCollected, 2)}`, record.combined.displayUSD, 'reader-facing USD-valued total');

process.stdout.write('BOS launchpad sale verification PASS\n');
process.stdout.write(`- completed Origins periods: ${record.periods.length}\n`);
process.stdout.write(`- combined token allocations: ${record.combined.tokensSold} BOS\n`);
process.stdout.write(`- combined Origins usdCollected counter: ${record.combined.usdCollected}\n`);
process.stdout.write('- the first Origins period includes the issuer-reported Phase 1 result; the combined total sums the two backend-period counters\n');
process.stdout.write('- preserved homepage and API responses match all three recorded SHA-256 hashes\n');
