import { FunctionFragment, JsonRpcProvider } from 'ethers';

import erc20Abi from './erc20-abi.json';

export async function hasContractFunction(provider: JsonRpcProvider, contractAddress: string, alternatives: string[]) {
  const bytecode = await provider.getCode(contractAddress);

  // No code : function is definitely not there
  if (bytecode.length <= 2) {
    return false;
  }

  const name = alternatives.find((x) => {
    const signature = erc20Abi.find((i) => i.name === x && i.type === 'function');
    const fragment = FunctionFragment.from(signature);
    // If the bytecode doesn't include the function selector, the function is definitely not present
    if (bytecode.includes(fragment.selector.slice(2))) {
      return true;
    }

    return false;
  });

  return name;
}

export async function isContractExist(provider: JsonRpcProvider, contractAddress: string) {
  // Get the contract bytecode
  const code = await provider.getCode(contractAddress);

  // If the code is not "0x", the contract exists
  return code !== '0x';
}

export async function getApproveFunction(provider: JsonRpcProvider, contractAddress: string) {
  const result = await hasContractFunction(provider, contractAddress, [
    'increaseAllowance',
    'increaseApproval',
    'approve',
  ]);

  if (!result) {
    throw new Error(`Approval function not supported in contract ${contractAddress}`);
  }

  return result;
}
