package BFTSmartBlockchain;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.util.HashSet;
import java.util.Set;

public class BlockchainTest {

	public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {

		int clientId = Integer.parseInt(args[0]);
		BlockchainClient blockchain = new BlockchainClient(clientId);
		
		// Select an Elliptic Curve (discrete logarithm) based key generator
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("EC");
		// Set algorithm parameters for key pair generator
		ECGenParameterSpec curveSpec = new ECGenParameterSpec("secp256k1");
		// Initialize the key pair generator with the curve specification and the random number generator
	    keyPairGen.initialize(curveSpec);	
	    // Generate a key pair
		KeyPair ECKeyPair = keyPairGen.generateKeyPair();
		ECPublicKey publicKey = (ECPublicKey) ECKeyPair.getPublic();
		ECPrivateKey privateKey = (ECPrivateKey) ECKeyPair.getPrivate();
		
		boolean exit = false;
		while(!exit) {
			System.out.println("Select an option:");
			System.out.println("0 - Exit");
			System.out.println("1 - Create a new transaction");
			System.out.println("2 - Get blockchain head");
			System.out.println("3 - Get block b blocks back from head");
			
			int cmd = Integer.parseInt(System.console().readLine("Option:"));
			
			switch (cmd) {
				case 0:
					exit = true;
					break;
				case 1:
					System.out.println("Create a new transaction");
					String data = System.console().readLine("Enter the data value:");
					Transaction tx = new Transaction(data.getBytes(), publicKey).Sign(privateKey);
					BlockchainReplyType result = blockchain.addTransaction(tx);
					switch (result) {
					case OK:
						System.out.println("Succesfully added Transaction to pool");
						break;
					case DUPLICATE:
						System.out.println("Transaction was duplicate");
						break;
					case BLOCK:
						System.out.println("Transaction added and new block mined");
					}
					break;
				case 2:
					Block head = blockchain.getHead();
					if (head != null)
						System.out.println("Head is: "+head.toString());
					else
						System.out.println("No head");
					break;
				case 3:
					System.out.println("Removing value in the map");
					int n = Integer.parseInt(System.console().readLine("How far back would you like to go:"));
					Block b = blockchain.getHead();
					while (n > 0 && b != null) {
						b = blockchain.getBlock(b.prevBlockHash);
						n--;
					}
					if (n == 0) {
						System.out.println("Here's your block: " + b);
					} else {
						System.out.println("Couldn't go that far back.");
					}
					break;
				default:
					break;
			}
		}
	}

}
