// 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 DeployWETHWithCREATEDirect
 * @notice Deploy WETH9 and WETH10 using CREATE to match genesis.json addresses
 * @dev Uses calculated nonce values to deploy to exact addresses
 *      
 *      Since the target addresses are in genesis.json, they should be
 *      deployable using CREATE with the correct deployer and nonce.
 */
contract DeployWETHWithCREATEDirect is Script {
    // Target addresses from genesis.json
    address constant TARGET_WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address constant TARGET_WETH10 = 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F;
    
    // Deployer addresses to try (from genesis.json with high balances)
    address constant DEPLOYER_1 = 0x0742D35CC6634c0532925A3b844bc9E7595f0Beb;
    address constant DEPLOYER_2 = 0xa55A4B57A91561e9df5a883D4883Bd4b1a7C4882;
    address constant DEPLOYER_3 = 0x4A666F96fC8764181194447A7dFdb7d471b301C8;
    
    function run() external {
        console.log("Deploying WETH9 and WETH10 using CREATE to match genesis addresses");
        console.log("WETH9 target:", vm.toString(TARGET_WETH9));
        console.log("WETH10 target:", vm.toString(TARGET_WETH10));
        
        vm.startBroadcast();
        
        // Deploy WETH9
        deployWETH9();
        
        // Deploy WETH10
        deployWETH10();
        
        vm.stopBroadcast();
        
        console.log("\n=== Deployment Complete ===");
    }
    
    function deployWETH9() internal {
        // Try deploying from different deployers
        address[] memory deployers = new address[](3);
        deployers[0] = DEPLOYER_1;
        deployers[1] = DEPLOYER_2;
        deployers[2] = DEPLOYER_3;
        
        for (uint256 i = 0; i < deployers.length; i++) {
            address deployer = deployers[i];
            uint256 nonce = vm.getNonce(deployer);
            
            console.log("\nTrying deployer:", vm.toString(deployer));
            console.log("Current nonce:", nonce);
            
            // Calculate what address this nonce would produce
            // For now, just try deploying and see what address we get
            // In production, we'd calculate the nonce first
            
            // Use prank to deploy from this address
            vm.startBroadcast(deployer);
            
            // Check if contract already exists
            uint256 codeSize;
            assembly {
                codeSize := extcodesize(TARGET_WETH9)
            }
            
            if (codeSize > 0) {
                console.log("WETH9 already exists at target address");
                verifyWETH9();
                vm.stopBroadcast();
                return;
            }
            
            // Deploy WETH9
            WETH weth = new WETH();
            address deployedAddress = address(weth);
            
            console.log("Deployed at:", vm.toString(deployedAddress));
            console.log("Target:", vm.toString(TARGET_WETH9));
            
            if (deployedAddress == TARGET_WETH9) {
                console.log("Successfully deployed WETH9 to target address!");
                verifyWETH9();
                vm.stopBroadcast();
                return;
            } else {
                console.log("Address mismatch - trying next deployer...");
                vm.stopBroadcast();
            }
        }
        
        console.log("Could not deploy to target address with any deployer");
        console.log("You may need to calculate the exact nonce first");
    }
    
    function deployWETH10() internal {
        // Try deploying from different deployers
        address[] memory deployers = new address[](3);
        deployers[0] = DEPLOYER_1;
        deployers[1] = DEPLOYER_2;
        deployers[2] = DEPLOYER_3;
        
        for (uint256 i = 0; i < deployers.length; i++) {
            address deployer = deployers[i];
            uint256 nonce = vm.getNonce(deployer);
            
            console.log("\nTrying deployer:", vm.toString(deployer));
            console.log("Current nonce:", nonce);
            
            vm.startBroadcast(deployer);
            
            // Check if contract already exists
            uint256 codeSize;
            assembly {
                codeSize := extcodesize(TARGET_WETH10)
            }
            
            if (codeSize > 0) {
                console.log("WETH10 already exists at target address");
                verifyWETH10();
                vm.stopBroadcast();
                return;
            }
            
            // Deploy WETH10
            WETH10 weth10 = new WETH10();
            address deployedAddress = address(weth10);
            
            console.log("Deployed at:", vm.toString(deployedAddress));
            console.log("Target:", vm.toString(TARGET_WETH10));
            
            if (deployedAddress == TARGET_WETH10) {
                console.log("Successfully deployed WETH10 to target address!");
                verifyWETH10();
                vm.stopBroadcast();
                return;
            } else {
                console.log("Address mismatch - trying next deployer...");
                vm.stopBroadcast();
            }
        }
        
        console.log("Could not deploy to target address with any deployer");
        console.log("You may need to calculate the exact nonce first");
    }
    
    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());
    }
}

