#!/usr/bin/env node
/**
 * Address Checksum Validator and Fixer
 * Validates and optionally fixes EIP-55 checksummed addresses in token lists
 */

import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
import { ethers } from 'ethers';

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

function isChecksummed(address) {
  try {
    return ethers.isAddress(address) && address === ethers.getAddress(address);
  } catch {
    return false;
  }
}

function checksumAddress(address) {
  try {
    // Convert to lowercase first if it's not valid, then checksum
    return ethers.getAddress(address.toLowerCase());
  } catch {
    return null;
  }
}

function validateAndFixAddresses(filePath, dryRun = true) {
  console.log(`\n🔍 ${dryRun ? 'Validating' : 'Fixing'} addresses in: ${filePath}\n`);

  // Read token list file
  let tokenList;
  try {
    const fileContent = readFileSync(filePath, 'utf-8');
    tokenList = JSON.parse(fileContent);
  } catch (error) {
    console.error('❌ Error reading or parsing token list file:');
    console.error(`   ${error.message}`);
    process.exit(1);
  }

  const issues = [];
  const fixed = [];

  // Check all addresses
  if (tokenList.tokens && Array.isArray(tokenList.tokens)) {
    tokenList.tokens.forEach((token, index) => {
      if (token.address) {
        if (!isChecksummed(token.address)) {
          const checksummed = checksumAddress(token.address);
          if (checksummed) {
            issues.push({
              index,
              token: token.symbol || token.name,
              original: token.address,
              checksummed,
              type: 'non-checksummed'
            });
            
            if (!dryRun) {
              token.address = checksummed;
              fixed.push({
                index,
                token: token.symbol || token.name,
                original: token.address,
                fixed: checksummed
              });
            }
          } else {
            issues.push({
              index,
              token: token.symbol || token.name,
              original: token.address,
              checksummed: null,
              type: 'invalid'
            });
          }
        }
      }
    });
  }

  // Report results
  if (issues.length === 0) {
    console.log('✅ All addresses are properly checksummed!\n');
    return 0;
  }

  console.log(`Found ${issues.length} address issue(s):\n`);
  issues.forEach(issue => {
    if (issue.type === 'invalid') {
      console.error(`❌ Token[${issue.index}] (${issue.token}): Invalid address format: ${issue.original}`);
    } else {
      console.log(`⚠️  Token[${issue.index}] (${issue.token}):`);
      console.log(`   Original: ${issue.original}`);
      console.log(`   Checksummed: ${issue.checksummed}`);
    }
  });

  if (!dryRun && fixed.length > 0) {
    console.log(`\n✏️  Fixed ${fixed.length} address(es)\n`);
    
    // Write back to file
    writeFileSync(filePath, JSON.stringify(tokenList, null, 2) + '\n', 'utf-8');
    console.log(`✅ Updated file: ${filePath}\n`);
  } else if (dryRun && issues.some(i => i.type !== 'invalid')) {
    console.log(`\n💡 Run with --fix to automatically fix checksummed addresses\n`);
  }

  return issues.some(i => i.type === 'invalid') ? 1 : 0;
}

// Main
const args = process.argv.slice(2);
const filePath = args.find(arg => !arg.startsWith('--')) || resolve(__dirname, '../lists/dbis-138.tokenlist.json');
const dryRun = !args.includes('--fix');

if (!filePath) {
  console.error('Usage: node checksum-addresses.js [path/to/token-list.json] [--fix]');
  process.exit(1);
}

const exitCode = validateAndFixAddresses(filePath, dryRun);
process.exit(exitCode);

