defmodule CLI.MockHttpClient do
  @moduledoc """
  Simple mock client used instead of Ethereumex.HttpClient
  """

  @blocks [
    %{
      "difficulty" => "0x100000",
      "extraData" => "0x3535353535353535353535353535353535353535353535353535353535353535",
      "gasLimit" => "0x1000000",
      "gasUsed" => "0x0",
      "hash" => "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
      "logsBloom" =>
        "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "miner" => "0x0000000000000000000000000000000000000000",
      "mixHash" => "0x0000000000000000000000000000000000000000000000000000000000000000",
      "nonce" => "0x0000000000000042",
      "number" => "0x0",
      "parentHash" => "0x0000000000000000000000000000000000000000000000000000000000000000",
      "receiptsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
      "size" => "0x21c",
      "stateRoot" => "0x217b0bbcfb72e2d57e28f33cb361b9983513177755dc3f33ce3e7022ed62b77b",
      "timestamp" => "0x0",
      "totalDifficulty" => "0x100000",
      "transactions" => [],
      "transactionsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "uncles" => []
    },
    %{
      "difficulty" => "0xf3a00",
      "extraData" => "0xd883010503846765746887676f312e372e318664617277696e",
      "gasLimit" => "0xffc001",
      "gasUsed" => "0x0",
      "hash" => "0x41800b5c3f1717687d85fc9018faac0a6e90b39deaa0b99e7fe4fe796ddeb26a",
      "logsBloom" =>
        "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "miner" => "0xd1aeb42885a43b72b518182ef893125814811048",
      "mixHash" => "0x0f98b15f1a4901a7e9204f3c500a7bd527b3fb2c3340e12176a44b83e414a69e",
      "nonce" => "0x0ece08ea8c49dfd9",
      "number" => "0x1",
      "parentHash" => "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
      "receiptsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
      "size" => "0x218",
      "stateRoot" => "0xc7b01007a10da045eacb90385887dd0c38fcb5db7393006bdde24b93873c334b",
      "timestamp" => "0x58318da2",
      "totalDifficulty" => "0x1f3a00",
      "transactions" => [],
      "transactionsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "uncles" => []
    }
  ]

  def eth_block_number() do
    {:ok, "0x2"}
  end

  def eth_get_block_by_number(number_hex, true) do
    number =
      number_hex
      |> load_hex()
      |> :binary.decode_unsigned()

    if block = Enum.at(@blocks, number) do
      {:ok, block}
    else
      {:error, "MockClient: failed to get block #{number}"}
    end
  end

  @spec load_hex(String.t()) :: binary()
  defp load_hex("0x" <> hex_string) do
    padded_hex_string =
      if rem(byte_size(hex_string), 2) == 1, do: "0" <> hex_string, else: hex_string

    {:ok, hex} = Base.decode16(padded_hex_string, case: :lower)

    hex
  end
end
