// 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 CWTokenMarketRegistryTest is Test {
    CWTokenMarketRegistry registry;
    MockErc20 token;
    CWTokenUsdFeed feed;

    function setUp() public {
        registry = new CWTokenMarketRegistry(address(this));
        token = new MockErc20(6, 15_452_106_931_334_998_000_000);
        feed = new CWTokenUsdFeed(registry, address(token), "test cWUSD / USD");
        registry.registerToken(address(token), 6, 100_000_000, address(0), true, address(feed));
    }

    function test_latestRoundData_faceBootstrap() public view {
        (, int256 answer,,,) = feed.latestRoundData();
        assertEq(answer, 100_000_000);
    }

    function test_onchainMarketCap() public view {
        uint256 cap = registry.onchainMarketCapUsdE8(address(token));
        assertEq(cap, 15_452_106_931_334_998_000_000 * 100_000_000 / 1e6);
    }

    function test_publishPrice_updatesFeed() public {
        registry.publishPrice(address(token), 99_500_000, "univ3_twap");
        (, int256 answer,,,) = feed.latestRoundData();
        assertEq(answer, 99_500_000);
    }

    function test_publishPrice_revertsOutsidePegBand() public {
        vm.expectRevert(bytes("peg band"));
        registry.publishPrice(address(token), 50_000_000, "bad");
    }

    function test_registerToken_revertsFeedMismatch() public {
        CWTokenUsdFeed badFeed = new CWTokenUsdFeed(registry, address(0xBEEF), "bad");
        vm.expectRevert(bytes("feed mismatch"));
        registry.registerToken(address(0xCAFE), 6, 100_000_000, address(0), true, address(badFeed));
    }

    function test_recordX402Settlement() public {
        registry.recordX402Settlement(
            address(token),
            address(0x4A66),
            address(0x6435),
            10_000,
            10_000,
            8453,
            bytes32(uint256(1)),
            keccak256("resource")
        );
        (,,,,,,,, uint256 settlementCount) = registry.tokens(address(token));
        assertEq(settlementCount, 1);
    }

    function test_pauseBlocksPublish() public {
        registry.pause();
        vm.expectRevert(bytes("paused"));
        registry.publishPrice(address(token), 100_000_000, "x");
    }
}

contract MockErc20 {
    uint8 public decimals;
    uint256 public totalSupply;

    constructor(uint8 d, uint256 supply) {
        decimals = d;
        totalSupply = supply;
    }
}
