// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {Script, console} from "forge-std/Script.sol";
import {WETH} from "../contracts/tokens/WETH.sol";
import {WETH10} from "../contracts/tokens/WETH10.sol";

/**
 * @title DeployWETHUsingCREATE
 * @notice Deploy WETH9 and WETH10 using CREATE opcode to match genesis.json addresses
 * @dev Since addresses are pre-allocated in genesis.json, we can deploy using CREATE
 *      by finding the correct deployer/nonce combination OR by deploying sequentially
 *      from a known deployer until we reach the target addresses.
 *      
 *      This script attempts to deploy using normal CREATE (not CREATE2) which will
 *      produce addresses based on the deployer's nonce.
 */
contract DeployWETHUsingCREATE is Script {
    // Target addresses from genesis.json
    address constant TARGET_WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address constant TARGET_WETH10 = 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F;
    
    // Deployer from PRIVATE_KEY
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        address deployer = vm.addr(deployerPrivateKey);
        
        console.log("Deploying WETH9 and WETH10 using CREATE");
        console.log("Deployer:", vm.toString(deployer));
        console.log("WETH9 target:", vm.toString(TARGET_WETH9));
        console.log("WETH10 target:", vm.toString(TARGET_WETH10));
        
        vm.startBroadcast(deployerPrivateKey);
        
        // Check current nonce
        uint256 currentNonce = vm.getNonce(deployer);
        console.log("Current deployer nonce:", currentNonce);
        
        // Check if contracts already exist
        if (checkContractExists(TARGET_WETH9)) {
            console.log("WETH9 already exists at target address");
            verifyWeth9();
        } else {
            console.log("Deploying WETH9...");
            WETH weth9 = new WETH();
            address deployedAddress = address(weth9);
            console.log("WETH9 deployed at:", vm.toString(deployedAddress));
            
            if (deployedAddress == TARGET_WETH9) {
                console.log("Successfully deployed WETH9 to target address!");
                verifyWeth9();
            } else {
                console.log("Deployed to different address");
                console.log("Target:", vm.toString(TARGET_WETH9));
                console.log("Got:", vm.toString(deployedAddress));
            }
        }
        
        if (checkContractExists(TARGET_WETH10)) {
            console.log("WETH10 already exists at target address");
            verifyWeth10();
        } else {
            console.log("Deploying WETH10...");
            WETH10 weth10 = new WETH10();
            address deployedAddress = address(weth10);
            console.log("WETH10 deployed at:", vm.toString(deployedAddress));
            
            if (deployedAddress == TARGET_WETH10) {
                console.log("Successfully deployed WETH10 to target address!");
                verifyWeth10();
            } else {
                console.log("Deployed to different address");
                console.log("Target:", vm.toString(TARGET_WETH10));
                console.log("Got:", vm.toString(deployedAddress));
            }
        }
        
        vm.stopBroadcast();
        
        console.log("\n=== Deployment Complete ===");
        console.log("Note: If addresses don't match, you may need to:");
        console.log("  1. Use a different deployer address");
        console.log("  2. Adjust deployer nonce to match target addresses");
        console.log("  3. Or use vm.etch in fork/test mode");
    }
    
    function checkContractExists(address addr) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(addr)
        }
        return size > 0;
    }
    
    function verifyWeth9() internal view {
        WETH weth = WETH(payable(TARGET_WETH9));
        console.log("WETH9 name:", weth.name());
        console.log("WETH9 symbol:", weth.symbol());
        console.log("WETH9 decimals:", weth.decimals());
    }
    
    function verifyWeth10() internal view {
        WETH10 weth10 = WETH10(payable(TARGET_WETH10));
        console.log("WETH10 name:", weth10.name());
        console.log("WETH10 symbol:", weth10.symbol());
        console.log("WETH10 decimals:", weth10.decimals());
    }
}

