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

import {Script, console} from "forge-std/Script.sol";
import {CompliantWrappedToken} from "../../contracts/tokens/CompliantWrappedToken.sol";
import {USDWPublicWrapVault} from "../../contracts/bridge/integration/USDWPublicWrapVault.sol";

/**
 * @title DeployUSDWPublicWrapVault
 * @notice Deploy the native USDW <-> cWUSDW wrap vault for a public chain.
 * @dev Use with an existing cWUSDW deployment on BSC or a newly deployed cWUSDW on Polygon.
 *
 * Env:
 *   PRIVATE_KEY (required)
 *   USDW_NATIVE_ADDRESS (required)     // e.g. dwinUsdWinPublic.chains.56.usdwCurrent
 *   CWUSDW_ADDRESS (required)          // cWUSDW contract on the current public chain
 *   USDW_WRAP_ADMIN (optional)         // additional admin to grant after deployment
 *   USDW_WRAP_OPERATOR (optional)      // reserve seeding operator; default admin/deployer
 *   USDW_WRAP_EMERGENCY_ADMIN (optional)
 *   USDW_WRAP_GRANT_TOKEN_ROLES=1      // grant MINTER_ROLE and BURNER_ROLE on cWUSDW to the vault
 *   USDW_WRAP_STRICT_ADMIN=1           // revoke deployer DEFAULT_ADMIN_ROLE after additional grants
 */
contract DeployUSDWPublicWrapVault is Script {
    function run() external {
        uint256 pk = vm.envUint("PRIVATE_KEY");
        address deployer = vm.addr(pk);
        address nativeUsdw = vm.envAddress("USDW_NATIVE_ADDRESS");
        address wrappedUsdw = vm.envAddress("CWUSDW_ADDRESS");
        address admin = vm.envOr("USDW_WRAP_ADMIN", deployer);
        address reserveOperator = vm.envOr("USDW_WRAP_OPERATOR", admin);
        address emergencyAdmin = vm.envOr("USDW_WRAP_EMERGENCY_ADMIN", admin);
        bool grantTokenRoles = vm.envOr("USDW_WRAP_GRANT_TOKEN_ROLES", uint256(0)) == 1;
        bool strictAdmin = vm.envOr("USDW_WRAP_STRICT_ADMIN", uint256(0)) == 1;

        vm.startBroadcast(pk);

        USDWPublicWrapVault vault = new USDWPublicWrapVault(deployer, nativeUsdw, wrappedUsdw);

        if (admin != deployer) {
            vault.grantRole(vault.DEFAULT_ADMIN_ROLE(), admin);
            vault.grantRole(vault.RESERVE_OPERATOR_ROLE(), admin);
            vault.grantRole(vault.EMERGENCY_ADMIN_ROLE(), admin);
        }
        if (reserveOperator != admin && reserveOperator != deployer) {
            vault.grantRole(vault.RESERVE_OPERATOR_ROLE(), reserveOperator);
        }
        if (emergencyAdmin != admin && emergencyAdmin != deployer) {
            vault.grantRole(vault.EMERGENCY_ADMIN_ROLE(), emergencyAdmin);
        }

        if (grantTokenRoles) {
            CompliantWrappedToken token = CompliantWrappedToken(wrappedUsdw);
            token.grantRole(token.MINTER_ROLE(), address(vault));
            token.grantRole(token.BURNER_ROLE(), address(vault));
        }

        if (strictAdmin && admin != deployer) {
            vault.revokeRole(vault.DEFAULT_ADMIN_ROLE(), deployer);
        }

        console.log("USDWPublicWrapVault", address(vault));
        console.log("  nativeUsdw", nativeUsdw);
        console.log("  wrappedUsdw", wrappedUsdw);
        console.log("  deployer", deployer);
        console.log("  admin", admin);
        console.log("  reserveOperator", reserveOperator);
        console.log("  emergencyAdmin", emergencyAdmin);
        console.log("  grantTokenRoles", grantTokenRoles);
        console.log("  strictAdmin", strictAdmin);

        vm.stopBroadcast();
    }
}
