import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by terry on 7/4/18.
 */


public class Proof {

    public static void main(String[] args) {

        int level = 1;

        Map<String, String> txHashes3 = new HashMap<>();

        Map<String, String> newHashMap = new HashMap<>();

        txHashes3.put("cfce9664889e17fa006cfa23dd82852a999f9a748478cf325e3791241dd27a50", "12");
        txHashes3.put("ae22ea6889a5712eb2e13736ce4586afd310295c6ddbbc2b56b1305441017a70", "11");
        txHashes3.put("932e4b5b88444f9001279f3e6b9f8c9144b30194a47723f6ffe46e2c83433d20", "22");
        txHashes3.put("14064970f7b3947cc046c094b4d0104f71d74fd74f6838734d201544cf47fff2", "31");
        txHashes3.put("52b7d99720b90bb50ee94a194ecf5de19c0095cd8e814443ad307f9245c65fdb", "42");

        while (level < 5) {

            byte[] bHashlist1 = new byte[100];
            byte[] bHashlist2 = new byte[100];


            System.out.println("Level: " + level);
            for (String key : txHashes3.keySet())

            {
                int value = Integer.parseInt(txHashes3.get(key).substring(0, 1));
                String order =(txHashes3.get(key).substring(1));
                
                if (value == level) {
                    newHashMap.put(key, order);
                }
            }

            System.out.println();
            System.out.println("newHashMap: " + newHashMap.toString());

            Boolean flag = true;
            String temp = "";

            for (String key2 : newHashMap.keySet()) {
                String sequence = newHashMap.get(key2);
                //System.out.println("key:" + key2 + "," + sequence);


                if (sequence.equals("1")) {
                    bHashlist1 = hexStringToByteArray(key2);
                    flag = true;
                    System.out.println("1:" + key2);
                }

                if (sequence.equals("2")) {
                    bHashlist2 = hexStringToByteArray(key2);
                    flag = false;
                    System.out.println("2:" + key2);
                }

                if (sequence.equals("?")) {
                    temp = key2;
                }
            }

            if (temp != "" && flag) {
                bHashlist2 = hexStringToByteArray(temp);
                System.out.println("2:" + temp);
            }
            if (temp != "" && !flag) {
                bHashlist1 = hexStringToByteArray(temp);
                System.out.println("1:" + temp);
            }


            byte[] newbHashlist1 = reverseByteArray(bHashlist1);
            byte[] newbHashlist2 = reverseByteArray(bHashlist2);
            byte[] combined = combineByteArray(newbHashlist1, newbHashlist2);

            String combinedHash = generateHash(combined);
            System.out.println("Branch hash is: " + combinedHash);
            System.out.println();
            level++;
            txHashes3.put(combinedHash, Integer.toString(level) + "?");
            System.out.println(txHashes3.toString());
            System.out.println();
            newHashMap.clear();
        }

        if(level == 5){

            String root = "";
            for (String key : txHashes3.keySet())

            {
                int value = Integer.parseInt(txHashes3.get(key).substring(0, 1));

                if (value == level) {
                    root = key;
                }
            }

            System.out.println("Root is:");
            System.out.println(root);
        }
    }



    public static String generateHash(byte [] value) {
        String hash = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");

            byte[] bytes = md.digest(value);
            md.reset();

            byte[] bytes2 = md.digest(bytes);

            byte[] bytes3 = reverseByteArray(bytes2);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bytes3.length; i++) {
                sb.append(Integer.toString((bytes3[i] & 0xff) + 0x100, 16).substring(1));
            }
            hash = sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hash;
    }



    public static byte[] reverseByteArray (byte [] bArray) {

        for (int i = 0, j = bArray.length - 1; i < j; i++, j--)
        {
            byte b = bArray[i];
            bArray[i] = bArray[j];
            bArray[j] = b;
        }

        return bArray;
    }


    public static  byte[] combineByteArray (byte [] first, byte [] second) {

        byte[] one = first;
        byte[] two = second;
        byte[] combined = new byte[one.length + two.length];

        for (int i = 0; i < combined.length; ++i)
        {
            combined[i] = i < one.length ? one[i] : two[i - one.length];
        }

        return combined;
    }


    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

}
