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

import {Script, console} from "forge-std/Script.sol";
import {CWNavOracle} from "../contracts/cw-settlement/CWNavOracle.sol";
import {CWRedemptionQueue} from "../contracts/cw-settlement/CWRedemptionQueue.sol";
import {CWStabilityFund} from "../contracts/cw-settlement/CWStabilityFund.sol";
import {CWBuybackExecutor} from "../contracts/cw-settlement/CWBuybackExecutor.sol";
import {CWProtocolTreasury} from "../contracts/cw-settlement/CWProtocolTreasury.sol";
import {CWReserveVerifier} from "../contracts/bridge/integration/CWReserveVerifier.sol";

interface ICWMultiTokenBridgeL1Admin {
    function setReserveVerifier(address newVerifier) external;
}

/**
 * @title DeployCWReserveSettlementStack
 * @notice Deploy NAV oracle, redemption queue, stability fund, buyback, treasury, and reserve verifier on Chain 138.
 *
 * Env:
 *   PRIVATE_KEY, RPC_URL_138
 *   CW_L1_BRIDGE (default 0x152ed3e9912161b76bdfd368d0c84b7c31c10de7)
 *   CW_RESERVE_SYSTEM (default 0x607e97cD626f209facfE48c1464815DDE15B5093)
 *   CW_CANONICAL_USDT / CW_CANONICAL_USDC
 *   CW_ATTACH_VERIFIER_TO_L1=1
 */
contract DeployCWReserveSettlementStack is Script {
    function run() external {
        uint256 privateKey = vm.envUint("PRIVATE_KEY");
        address admin = vm.addr(privateKey);

        address l1Bridge = vm.envOr("CW_L1_BRIDGE", address(0x152eD3e9912161b76BDFd368D0C84B7C31C10dE7));
        address reserveSystem = vm.envOr("CW_RESERVE_SYSTEM", address(0x607e97cD626f209facfE48c1464815DDE15B5093));
        address canonicalUSDT = vm.envOr("CW_CANONICAL_USDT", address(0x93E66202A11B1772E55407B32B44e5Cd8eda7f22));
        address canonicalUSDC = vm.envOr("CW_CANONICAL_USDC", address(0xf22258f57794CC8E06237084b353Ab30fFfa640b));
        bool attachVerifier = vm.envOr("CW_ATTACH_VERIFIER_TO_L1", uint256(0)) == 1;
        bool skipVerifierDeploy = vm.envOr("CW_SKIP_RESERVE_VERIFIER", uint256(1)) == 1;

        vm.startBroadcast(privateKey);

        address verifierAddr;
        if (skipVerifierDeploy) {
            verifierAddr = address(0);
        } else {
            CWReserveVerifier verifier = new CWReserveVerifier(admin, l1Bridge, address(0), reserveSystem);
            verifierAddr = address(verifier);
            if (attachVerifier) {
                ICWMultiTokenBridgeL1Admin(l1Bridge).setReserveVerifier(verifierAddr);
            }
            verifier.configureToken(canonicalUSDT, address(0), false, false, false);
            verifier.configureToken(canonicalUSDC, address(0), false, false, false);
        }

        CWNavOracle navOracle = new CWNavOracle(admin, l1Bridge, reserveSystem);
        CWRedemptionQueue redemptionQueue = new CWRedemptionQueue(admin);
        CWStabilityFund stabilityFund = new CWStabilityFund(admin);
        CWProtocolTreasury treasury = new CWProtocolTreasury(admin, address(0));
        CWBuybackExecutor buyback = new CWBuybackExecutor(admin, verifierAddr, address(treasury));

        treasury.setBuybackExecutor(address(buyback));

        navOracle.configureToken(canonicalUSDT, address(0));
        navOracle.configureToken(canonicalUSDC, address(0));

        vm.stopBroadcast();

        console.log("CWReserveVerifier:", verifierAddr);
        console.log("CWNavOracle:", address(navOracle));
        console.log("CWRedemptionQueue:", address(redemptionQueue));
        console.log("CWStabilityFund:", address(stabilityFund));
        console.log("CWProtocolTreasury:", address(treasury));
        console.log("CWBuybackExecutor:", address(buyback));
    }
}
