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

import "forge-std/Test.sol";
import "../../contracts/iso4217w/registry/TokenRegistry.sol";

contract TokenRegistryTest is Test {
    TokenRegistry public registry;

    address public admin = address(0x1);
    address public token = address(0x100);
    address public custodian = address(0x2);
    address public mintController = address(0x3);
    address public burnController = address(0x4);

    string public constant CURRENCY_CODE = "USD";
    string public constant TOKEN_SYMBOL = "USDW";

    function setUp() public {
        registry = new TokenRegistry(admin);
    }

    function test_RegisterToken() public {
        vm.prank(admin);
        registry.registerToken(CURRENCY_CODE, token, TOKEN_SYMBOL, 2, custodian);

        address registeredToken = registry.getTokenAddress(CURRENCY_CODE);
        assertEq(registeredToken, token, "Token should be registered");

        TokenRegistry.TokenInfo memory info = registry.getTokenInfo(CURRENCY_CODE);
        assertEq(info.tokenAddress, token);
        assertEq(keccak256(bytes(info.tokenSymbol)), keccak256(bytes(TOKEN_SYMBOL)));
        assertEq(info.decimals, 2);
        assertEq(info.custodian, custodian);
        assertTrue(info.isActive, "Token should be active");
    }

    function test_RegisterToken_RevertIfInvalidCurrency() public {
        vm.prank(admin);
        vm.expectRevert("TokenRegistry: GRU isolation violation");
        registry.registerToken("GRU", token, "GRUW", 2, custodian); // GRU not allowed
    }

    function test_SetMintController() public {
        vm.prank(admin);
        registry.registerToken(CURRENCY_CODE, token, TOKEN_SYMBOL, 2, custodian);

        vm.prank(admin);
        registry.setMintController(CURRENCY_CODE, mintController);

        TokenRegistry.TokenInfo memory info = registry.getTokenInfo(CURRENCY_CODE);
        assertEq(info.mintController, mintController);
    }

    function test_DeactivateToken() public {
        vm.prank(admin);
        registry.registerToken(CURRENCY_CODE, token, TOKEN_SYMBOL, 2, custodian);

        vm.prank(admin);
        registry.deactivateToken(CURRENCY_CODE);

        TokenRegistry.TokenInfo memory info = registry.getTokenInfo(CURRENCY_CODE);
        assertFalse(info.isActive, "Token should be deactivated");
    }
}
