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

import {Test} from "forge-std/Test.sol";
import {console2} from "forge-std/console2.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {DODOIntegrationExternalUnwinder} from "../../contracts/flash/DODOIntegrationExternalUnwinder.sol";

contract EstimateMainnetCwUnwindForkTest is Test {
    address constant DODO_PMM_INTEGRATION_MAINNET = 0xa9F284eD010f4F7d7F8F201742b49b9f58e29b84;
    address constant POOL_CWUSDC_USDC = 0x69776fc607e9edA8042e320e7e43f54d06c68f0E;
    address constant POOL_CWUSDT_USDT = 0x79156F6B7bf71a1B72D78189B540A89A6C13F6FC;
    address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
    address constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
    address constant CWUSDC = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
    address constant CWUSDT = 0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE;

    DODOIntegrationExternalUnwinder internal unwinder;

    function setUp() public {
        string memory rpcUrl = vm.envString("ETHEREUM_MAINNET_RPC");
        vm.createSelectFork(rpcUrl);
        unwinder = new DODOIntegrationExternalUnwinder(DODO_PMM_INTEGRATION_MAINNET);
    }

    function testEstimateDirectUnwinds() public {
        uint256[] memory sizes = new uint256[](10);
        sizes[0] = 100_000; // 0.1
        sizes[1] = 1_000_000; // 1
        sizes[2] = 5_000_000; // 5
        sizes[3] = 10_000_000; // 10
        sizes[4] = 25_000_000; // 25
        sizes[5] = 50_000_000; // 50
        sizes[6] = 100_000_000; // 100
        sizes[7] = 250_000_000; // 250
        sizes[8] = 500_000_000; // 500
        sizes[9] = 1_000_000_000; // 1000

        console2.log("cWUSDC -> USDC");
        _logCurve(CWUSDC, USDC, POOL_CWUSDC_USDC, sizes);

        console2.log("cWUSDT -> USDT");
        _logCurve(CWUSDT, USDT, POOL_CWUSDT_USDT, sizes);
    }

    function _logCurve(address tokenIn, address tokenOut, address pool, uint256[] memory sizes) internal {
        for (uint256 i = 0; i < sizes.length; i++) {
            uint256 snap = vm.snapshotState();
            uint256 amountIn = sizes[i];
            deal(tokenIn, address(this), amountIn);
            IERC20(tokenIn).approve(address(unwinder), amountIn);
            try unwinder.unwind(tokenIn, tokenOut, amountIn, 1, abi.encode(pool)) returns (uint256 amountOut) {
                console2.log("in_raw", amountIn, "out_raw", amountOut);
            } catch {
                console2.log("in_raw", amountIn, "out_raw", uint256(0));
            }
            vm.revertToState(snap);
        }
    }
}
