import java.util.function.Consumer;

import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthBlock;
import org.web3j.protocol.core.methods.response.EthTransaction;
import org.web3j.protocol.core.methods.response.Transaction;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;

public class EthereumWeb3jFilter {

	public static void printTransaction(EthTransaction tx) {
		
	}
	
	public static void printBlock(EthBlock block) {
		
	}
	
	
	public static void main(String[] args) {

		/*
		 * Open a connection to the geth node using rpc
		 */
		Web3j web3 = Web3j.build(new HttpService("http://localhost:8545"));
		
		try {
			/*
			 * Use RPC send() to get the client version of geth
			 */
			Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send();
			String clientVersion = web3ClientVersion.getWeb3ClientVersion();
			System.out.println("Client is version: "+clientVersion);

	        Consumer<? super EthTransaction> pendingTxAction = new Consumer<EthTransaction>() {
				@Override
				public void accept(EthTransaction tx) {
			        System.out.println("Pending Transaction:");
			        System.out.println("  Tx Hash: " + tx.getTransaction().get().getHash());
			        System.out.println("  Block Hash: " + tx.getTransaction().get().getBlockHash());
			        System.out.println("  Block Number: " + tx.getTransaction().get().getBlockNumber());
			        System.out.println("  Tx Index: " + tx.getTransaction().get().getTransactionIndex());
			        System.out.println("  Gas: " + tx.getTransaction().get().getGas());
			        System.out.println("  Gas Price: " + tx.getTransaction().get().getGasPrice());
			        System.out.println("  From: " + tx.getTransaction().get().getFrom());
			        System.out.println("  To: " + tx.getTransaction().get().getTo());
				}
	        };
			web3.pendingTransactionFlowable().subscribe(tx -> printTransaction(tx););
			
	        Consumer<? super EthTransaction> txAction = new Consumer<EthTransaction>() {
				@Override
				public void accept(EthTransaction tx) {
			        System.out.println("Transaction:");
			        System.out.println("  Tx Hash: " + tx.getTransaction().get().getHash());
			        System.out.println("  Block Hash: " + tx.getTransaction().get().getBlockHash());
			        System.out.println("  Block Number: " + tx.getTransaction().get().getBlockNumber());
			        System.out.println("  Tx Index: " + tx.getTransaction().get().getTransactionIndex());
			        System.out.println("  Gas: " + tx.getTransaction().get().getGas());
			        System.out.println("  Gas Price: " + tx.getTransaction().get().getGasPrice());
			        System.out.println("  From: " + tx.getTransaction().get().getFrom());
			        System.out.println("  To: " + tx.getTransaction().get().getTo());
				}
	        };
			web3.transactionFlowable().subscribe((io.reactivex.functions.Consumer<? super Transaction>) txAction);
	        
	        Consumer<EthBlock> blockAction = new Consumer<EthBlock>() {
				@Override
				public void accept(EthBlock block) {
			        System.out.println("Block Info");
			        System.out.println("  Hash: " + block.getBlock().getHash());
			        System.out.println("  Parent: " + block.getBlock().getParentHash());
			        System.out.println("  Author: " + block.getBlock().getAuthor());
			        System.out.println("  Miner: " + block.getBlock().getMiner());
			        System.out.println("  Extra: " + block.getBlock().getExtraData());
			        for (String uncle : block.getBlock().getUncles()) {
			        	System.out.println("  Uncle: " + uncle);
			        }
			        System.out.println("  Nonce: " + block.getBlock().getNonce());
				}
	        };
			web3.blockFlowable(false).subscribe((io.reactivex.functions.Consumer<? super EthBlock>) blockAction);

			System.out.println("Press any key to exit");
			System.in.read();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		/*
		 * Close the RPC connection when we're done
		 */
		web3.shutdown();
	}

}
