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

import {Test} from "forge-std/Test.sol";
import {CWTokenMarketRegistry} from "../../contracts/mainnet-market/CWTokenMarketRegistry.sol";
import {CWTokenUsdFeed} from "../../contracts/mainnet-market/CWTokenUsdFeed.sol";

contract CWTokenMarketRegistryForkTest is Test {
    address constant CWUSDC = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
    address constant CWUSDT = 0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE;
    address constant POOL_CWUSDC = 0x1Cf2e685682C7F7beF508F0Af15Dfb5CDda01ee3;
    address constant POOL_CWUSDT = 0x6eF5A392BcbE42F3D0a855595bEa60CFf9451784;
    address constant CWBTC = 0x2BBe3c809386FA5349EB2da31E0848ee9f54EE59;
    address constant CHAINLINK_BTC_USD = 0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c;

    function test_fork_registerMainnetTokensAndMarketCap() public {
        string memory rpc = vm.envOr(string("ETHEREUM_MAINNET_RPC"), string("https://ethereum.publicnode.com"));
        vm.createSelectFork(rpc);

        CWTokenMarketRegistry registry = new CWTokenMarketRegistry(address(this));

        CWTokenUsdFeed feedUsdc = new CWTokenUsdFeed(registry, CWUSDC, "cWUSDC / USD");
        registry.registerToken(CWUSDC, 6, 100_000_000, POOL_CWUSDC, true, address(feedUsdc));

        CWTokenUsdFeed feedUsdt = new CWTokenUsdFeed(registry, CWUSDT, "cWUSDT / USD");
        registry.registerToken(CWUSDT, 6, 100_000_000, POOL_CWUSDT, true, address(feedUsdt));

        (, int256 usdcPx,,,) = feedUsdc.latestRoundData();
        assertEq(usdcPx, 100_000_000);

        uint256 mcap = registry.onchainMarketCapUsdE8(CWUSDC);
        assertGt(mcap, 0);

        assertEq(registry.tokenFeed(CWUSDC), address(feedUsdc));
        assertEq(registry.tokenCount(), 2);
    }

    function test_fork_registerCWBTWithChainlinkBtcUsd() public {
        string memory rpc = vm.envOr(string("ETHEREUM_MAINNET_RPC"), string("https://ethereum.publicnode.com"));
        vm.createSelectFork(rpc);

        (, int256 answer,,,) = AggregatorV3(CHAINLINK_BTC_USD).latestRoundData();
        assertGt(answer, 0);

        CWTokenMarketRegistry registry = new CWTokenMarketRegistry(address(this));
        uint64 faceUsdE8 = uint64(uint256(answer));

        CWTokenUsdFeed feed = new CWTokenUsdFeed(registry, CWBTC, "cWBTC / USD");
        registry.registerToken(CWBTC, 8, faceUsdE8, address(0), true, address(feed));

        (, int256 px,,,) = feed.latestRoundData();
        assertEq(px, answer);
        assertGt(registry.onchainMarketCapUsdE8(CWBTC), 0);
    }
}

interface AggregatorV3 {
    function latestRoundData()
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
