import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthBlock;
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 printPendingTransaction(Transaction tx) {
        System.out.println("Pending Transaction:");
        System.out.println("  Tx Hash: " + tx.getHash());
        System.out.println("  Block Hash: " + tx.getBlockHash());
        System.out.println("  Block Number: " + tx.getBlockNumber());
        System.out.println("  Tx Index: " + tx.getTransactionIndex());
        System.out.println("  Gas: " + tx.getGas());
        System.out.println("  Gas Price: " + tx.getGasPrice());
        System.out.println("  From: " + tx.getFrom());
        System.out.println("  To: " + tx.getTo());
        System.out.flush();
	}
	
	public static void printTransaction(Transaction tx) {
        System.out.println("Mined Transaction:");
        System.out.println("  Tx Hash: " + tx.getHash());
        System.out.println("  Block Hash: " + tx.getBlockHash());
        System.out.println("  Block Number: " + tx.getBlockNumber());
        System.out.println("  Tx Index: " + tx.getTransactionIndex());
        System.out.println("  Gas: " + tx.getGas());
        System.out.println("  Gas Price: " + tx.getGasPrice());
        System.out.println("  From: " + tx.getFrom());
        System.out.println("  To: " + tx.getTo());
        System.out.flush();
	}
	
	public static void printBlock(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());
        System.out.flush();
	}
	
	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);

			web3.pendingTransactionFlowable().subscribe(tx -> printPendingTransaction(tx));			
			web3.transactionFlowable().subscribe(tx -> printTransaction(tx));
			web3.blockFlowable(false).subscribe(block -> printBlock(block));

			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();
	}

}
