/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.apache.tuweni.eth.reference;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.crypto.SECP256K1.Signature;
import org.apache.tuweni.eth.Address;
import org.apache.tuweni.eth.Block;
import org.apache.tuweni.eth.BlockBody;
import org.apache.tuweni.eth.BlockHeader;
import org.apache.tuweni.eth.Hash;
import org.apache.tuweni.eth.Transaction;
import org.apache.tuweni.io.Resources;
import org.apache.tuweni.junit.BouncyCastleExtension;
import org.apache.tuweni.units.bigints.UInt256;
import org.apache.tuweni.units.ethereum.Gas;
import org.apache.tuweni.units.ethereum.Wei;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.errorprone.annotations.MustBeClosed;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

@ExtendWith(BouncyCastleExtension.class)
class BlockRLPTestSuite {

  private static ObjectMapper mapper = new ObjectMapper();

  @ParameterizedTest(name = "{index}. block {0}[{1}]")
  @MethodSource("readBlockChainTests")
  void testBlockRLP(String name, long blockIndex, Block block, String rlp, String hash) {
    Block rlpBlock = Block.fromHexString(rlp);
    assertEquals(block, rlpBlock);
    assertEquals(Bytes.fromHexString(rlp), block.toBytes());
    assertEquals(Hash.fromHexString(hash), block.header().hash());
    assertEquals(Hash.fromHexString(hash), rlpBlock.header().hash());
  }

  @MustBeClosed
  private static Stream<Arguments> readBlockChainTests() throws IOException {
    return Resources.find("**/BlockchainTests/**/*.json").flatMap(url -> {
      try (InputStream is = url.openConnection().getInputStream()) {
        return readTestCase(is);
      } catch (IOException e) {
        throw new UncheckedIOException(e);
      }
    }).filter(Objects::nonNull);
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static Stream<Arguments> readTestCase(InputStream is) throws IOException {
    Map<String, Map> test = mapper.readerFor(Map.class).readValue(is);
    if (test.isEmpty()) {
      return null;
    }
    String name = test.keySet().iterator().next();
    Map testData = test.get(name);
    List<Map> blocks = (List<Map>) testData.get("blocks");
    return IntStream.range(0, blocks.size()).boxed().filter(i -> blocks.get(i).containsKey("blockHeader")).map(i -> {
      Map block = blocks.get(i);
      return Arguments.of(name, i, createBlock(block), block.get("rlp"), ((Map) block.get("blockHeader")).get("hash"));
    });
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static BlockHeader createBlockHeader(Map headerData) {
    checkNotNull(headerData, headerData.toString());
    return new BlockHeader(
        Hash.fromHexString((String) headerData.get("parentHash")),
        Hash.fromHexString((String) headerData.get("uncleHash")),
        Address.fromHexString((String) headerData.get("coinbase")),
        Hash.fromHexString((String) headerData.get("stateRoot")),
        Hash.fromHexString((String) headerData.get("transactionsTrie")),
        Hash.fromHexString((String) headerData.get("receiptTrie")),
        Bytes.fromHexString((String) headerData.get("bloom")),
        UInt256.fromHexString((String) headerData.get("difficulty")),
        UInt256.fromHexString((String) headerData.get("number")),
        Gas.valueOf(UInt256.fromHexString((String) headerData.get("gasLimit"))),
        Gas.valueOf(UInt256.fromHexString((String) headerData.get("gasUsed"))),
        Instant.ofEpochSecond(Bytes.fromHexString((String) headerData.get("timestamp")).toLong()),
        Bytes.fromHexString((String) headerData.get("extraData")),
        Hash.fromHexString((String) headerData.get("mixHash")),
        Bytes.fromHexString((String) headerData.get("nonce")));
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private static Block createBlock(Map blockData) {
    Map headerData = (Map) blockData.get("blockHeader");
    BlockHeader header = createBlockHeader(headerData);
    List<Transaction> transactions = new ArrayList<>();
    for (Object txDataObj : (List) blockData.get("transactions")) {
      Map txData = (Map) txDataObj;

      Address toAddress = null;
      String toAddressString = (String) txData.get("to");
      if (toAddressString != null) {
        Bytes toAddressBytes = Bytes.fromHexString(toAddressString);
        toAddress = toAddressBytes.isEmpty() ? null : Address.fromBytes(toAddressBytes);
      }

      transactions.add(
          new Transaction(
              UInt256.fromHexString((String) txData.get("nonce")),
              Wei.valueOf(UInt256.fromHexString((String) txData.get("gasPrice"))),
              Gas.valueOf(UInt256.fromHexString((String) txData.get("gasLimit"))),
              toAddress,
              Wei.valueOf(UInt256.fromHexString((String) txData.get("value"))),
              Bytes.fromHexString((String) txData.get("data")),
              null,
              Signature.create(
                  (byte) ((int) Bytes.fromHexString((String) txData.get("v")).get(0) - 27),
                  Bytes.fromHexString((String) txData.get("r")).toUnsignedBigInteger(),
                  Bytes.fromHexString((String) txData.get("s")).toUnsignedBigInteger())));
    }
    List<BlockHeader> ommers = new ArrayList<>();
    for (Object ommerDataObj : (List) blockData.get("uncleHeaders")) {
      ommers.add(createBlockHeader((Map) ommerDataObj));
    }

    return new Block(header, new BlockBody(transactions, ommers));
  }
}
