#!/usr/bin/env node

/**
 * Sync TAX_RATE options from the on-chain Stake contract to kraiken-lib.
 *
 * The Stake.sol contract defines the canonical TAX_RATES array in basis points (yearly percentage * 100).
 * This script parses that array and regenerates kraiken-lib/src/taxRates.ts so that all front-end consumers
 * share a single source of truth that mirrors the deployed contract.
 */

import { readFileSync, writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import path from 'node:path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const stakeSourcePath = path.resolve(__dirname, '../onchain/src/Stake.sol');
const taxRatesDestPath = path.resolve(__dirname, '../kraiken-lib/src/taxRates.ts');

const source = readFileSync(stakeSourcePath, 'utf8');

const match = source.match(/uint256\[]\s+public\s+TAX_RATES\s*=\s*\[([^\]]+)\]/m);
if (!match) {
  throw new Error(`Unable to locate TAX_RATES array in ${stakeSourcePath}`);
}

const rawValues = match[1]
  .split(',')
  .map(value => value.trim())
  .filter(Boolean);

if (rawValues.length === 0) {
  throw new Error('TAX_RATES array is empty or failed to parse');
}

const taxRateOptions = rawValues.map((value, index) => {
  const basisPoints = Number(value.replace(/_/g, ''));
  if (!Number.isFinite(basisPoints)) {
    throw new Error(`Invalid TAX_RATES entry "${value}" at index ${index}`);
  }

  const yearlyPercent = basisPoints;
  const decimalRate = yearlyPercent / 100;
  const dailyPercent = yearlyPercent / 365;

  return {
    index,
    year: yearlyPercent,
    daily: Number(dailyPercent.toFixed(5)),
    decimal: Number(decimalRate.toFixed(2)),
  };
});

// Generate checksum for runtime validation
import { createHash } from 'node:crypto';
const taxRatesString = rawValues.join(',');
const checksum = createHash('sha256').update(taxRatesString).digest('hex').slice(0, 16);

const fileHeader = `/**
 * AUTO-GENERATED FILE — DO NOT EDIT
 *
 * Generated by scripts/sync-tax-rates.mjs from onchain/src/Stake.sol.
 * Run \`node scripts/sync-tax-rates.mjs\` after modifying the contract TAX_RATES array.
 */
`;

const interfaceDef = `export interface TaxRateOption {
  index: number;
  year: number;
  daily: number;
  decimal: number;
}
`;

const optionLines = taxRateOptions
  .map(option => `  { index: ${option.index}, year: ${option.year}, daily: ${option.daily}, decimal: ${option.decimal} }`)
  .join(',\n');

const content = `${fileHeader}
${interfaceDef}
export const TAX_RATE_OPTIONS: TaxRateOption[] = [
${optionLines}
];

/**
 * Checksum of the contract TAX_RATES array (first 16 chars of SHA-256).
 * Used for runtime validation to ensure kraiken-lib is in sync with deployed contracts.
 *
 * To validate at runtime:
 * 1. Read TAX_RATES array from the Stake contract
 * 2. Compute checksum: sha256(values.join(',')).slice(0, 16)
 * 3. Compare with TAX_RATES_CHECKSUM
 *
 * If mismatch: Run \`node scripts/sync-tax-rates.mjs\` and rebuild kraiken-lib.
 */
export const TAX_RATES_CHECKSUM = '${checksum}';

/**
 * Array of raw year values (matches contract uint256[] TAX_RATES exactly).
 * Used for runtime validation without needing to parse options.
 */
export const TAX_RATES_RAW = [${rawValues.join(', ')}];
`;

writeFileSync(taxRatesDestPath, content.trimStart() + '\n');
