contract ETHPool is Ownable{
    
    using SafeERC20 for IERC20;
    
    mapping(address=>bool) public supportedTokens;
    uint256 supportedTokensCount = 0;
    address[] public tokenAddresses;
    address public walletAddress;
    
    constructor () {
        walletAddress = msg.sender;
    }
    
    event Deposit(address indexed from, address indexed to, address token_address, uint256 value);
    event Withdraw(address indexed from, address indexed to, address token_address, uint256 value);

    function updateWalletAddress(address addr) public onlyOwner {
        walletAddress = addr;
    }

    function checkTokenAddressExists(address token_address) internal view returns (bool) {
        for (uint i = 0 ; i < tokenAddresses.length ; i ++ ) {
            if (tokenAddresses[i] == token_address ) {
                return true;
            }
        }
        return false;
    }
    
    function setToken(address token) public onlyOwner {
        require(checkTokenAddressExists(token) == false, "Token already set");
        supportedTokens[token] = true;
        tokenAddresses.push(token);
        supportedTokensCount = supportedTokensCount + 1;
    }
    
    function enableToken(address token) public onlyOwner {
        require(checkTokenAddressExists(token) == true, "Token not yet exists");
        require(supportedTokens[token] == false, "Token is already enabled");
        supportedTokens[token] = true;
        if ( ! checkTokenAddressExists(token) ) {
            tokenAddresses.push(token);
        }
        supportedTokensCount = supportedTokensCount + 1;
    }

    function disableToken(address token) public onlyOwner {
        (checkTokenAddressExists(token) == true, "Token not yet exists");
        require(supportedTokens[token] == true, "Token is already disabled");
        supportedTokens[token] = false;
        supportedTokensCount = supportedTokensCount - 1;
    }
    
    // get the tokens that we supports
    function getSupportedTokenAddresses() public view returns (address[] memory){
        address[] memory supportedTokenAddresses = new address[](supportedTokensCount);
        uint16 count = 0;
        for ( uint256 i = 0 ; i < tokenAddresses.length ; i ++ ){
            if (supportedTokens[tokenAddresses[i]]) {
                supportedTokenAddresses[count] = tokenAddresses[i];
                count = count + 1;
            }
        }
        return supportedTokenAddresses;
    }

    function deposit(address token, uint256 amount) public {
        require(supportedTokens[token], "TOKEN ADDRESS IS NOT SUPPORTED");
        
        uint256 balance = IERC20(token).balanceOf(address(msg.sender));
        require(balance >= amount, "Pool: INSUFFICIENT_INPUT_AMOUNT");

        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
        emit Deposit(msg.sender, address(this), token, amount);
    }

    function depositNative() public payable {
        require(supportedTokens[address(0)], "NATIVE TOKEN IS NOT SUPPORTED");
        emit Deposit(msg.sender, address(this), address(0), msg.value);
    }
    
    function withdrawToken(address token) public onlyOwner {
        uint256 balance = IERC20(token).balanceOf(address(this));  
        IERC20(token).transfer(walletAddress, balance);
        emit Withdraw(address(this), walletAddress, token, balance);
    }

    function withdrawNativeToken() public onlyOwner {
        uint256 balance = address(this).balance;
        payable(walletAddress).transfer(balance);
        emit Withdraw(address(this), walletAddress, address(0), balance);
    }
    
    function balanceOfToken(address token) public view onlyOwner returns (uint256 amount) {
        uint256 balance = IERC20(token).balanceOf(address(this));
        return balance;
    }

    function balanceOfNativeToken() public view onlyOwner returns (uint256 amount) {
        uint256 balance = address(this).balance;
        return balance;
    }
}
function getSupportedTokenAddresses() public view returns (address[] memory){
    address[] memory supportedTokenAddresses = new address[](supportedTokensCount);
    uint16 count = 0;
    for ( uint256 i = 0 ; i < tokenAddresses.length ; i ++ ){
        if (supportedTokens[tokenAddresses[i]]) {
            supportedTokenAddresses[count] = tokenAddresses[i];
            count = count + 1;
        }
    }
    return supportedTokenAddresses;
}

// get the tokens that we supports