package leigh.chain.etherium;

import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.RawTransactionManager;
import org.web3j.tx.TransactionManager;
import org.web3j.tx.response.NoOpProcessor;
import org.web3j.tx.response.TransactionReceiptProcessor;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.math.BigInteger;

public class SendTransaction {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(SendTransaction.class);
    public static int CHAIN_ID = 52;

    public static void main(String[] args) throws Exception {
        Web3j web3 = Web3j.build(new HttpService("http://localhost:8545"));

        // "/Users/aleigh/Library/Ethereum/keystore/UTC--2022-03-19T03-29-48.574324665Z--400a72097cdeea17525d9fe9cc975d23b8997ea3"
        // /Users/aleigh/Library/Ethereum/keystore/UTC--2022-03-19T18-40-38.284371000Z--21dc9adacb308530daa08c5258ae86a54e06aece

        Credentials credentials = WalletUtils.loadCredentials("",
                "/Users/aleigh/Library/Ethereum/keystore/UTC--2022-03-19T03-29-48.574324665Z--400a72097cdeea17525d9fe9cc975d23b8997ea3");
        TransactionReceiptProcessor transactionReceiptProcessor = new NoOpProcessor(web3);
        TransactionManager transactionManager = new RawTransactionManager(web3, credentials, CHAIN_ID, transactionReceiptProcessor);

        logger.info("TM from: {}", transactionManager.getFromAddress());

        BigInteger gasLimit = BigInteger.valueOf(31000);
        BigInteger gasPrice = Convert.toWei("21000", Convert.Unit.GWEI).toBigInteger();
        EthGetTransactionCount ethGetTransactionCount = web3.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST).send();
        BigInteger nonce = ethGetTransactionCount.getTransactionCount();
        logger.info("Current nonce: {}", nonce);

        // 6336

        RawTransaction rawTransaction = RawTransaction.createTransaction(
                nonce,
                gasPrice,
                gasLimit,
                "0x21dc9adacb308530daa08c5258ae86a54e06aece",
                BigInteger.valueOf(0), "Hello World!");
        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        // Convert it to Hexadecimal String to be sent to the node
        String hexValue = Numeric.toHexString(signedMessage);

        logger.info("Built message: {}", hexValue);

        EthSendTransaction ethSendTransaction = web3.ethSendRawTransaction(hexValue).send();

        String transactionHash = ethSendTransaction.getTransactionHash();

        logger.info("Result: {}", transactionHash);
    }

}