// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.tsp.ers;

import org.bouncycastle.util.Arrays;
import java.util.ArrayList;
import org.bouncycastle.asn1.tsp.PartialHashtree;
import org.bouncycastle.operator.DigestCalculator;
import java.util.List;

public class BinaryTreeRootCalculator implements ERSRootNodeCalculator
{
    private List<List<byte[]>> tree;
    
    @Override
    public byte[] computeRootHash(final DigestCalculator digestCalculator, final PartialHashtree[] array) {
        final SortedHashList list = new SortedHashList();
        for (int i = 0; i < array.length; ++i) {
            list.add(ERSUtil.computeNodeHash(digestCalculator, array[i]));
        }
        List<byte[]> list2 = list.toList();
        (this.tree = new ArrayList<List<byte[]>>()).add(list2);
        if (list2.size() > 1) {
            do {
                final ArrayList list3 = new ArrayList(list2.size() / 2 + 1);
                for (int j = 0; j <= list2.size() - 2; j += 2) {
                    list3.add((Object)ERSUtil.calculateBranchHash(digestCalculator, (byte[])list2.get(j), (byte[])list2.get(j + 1)));
                }
                if (list2.size() % 2 == 1) {
                    list3.add(list2.get(list2.size() - 1));
                }
                this.tree.add((ArrayList)list3);
                list2 = (List<byte[]>)list3;
            } while (list2.size() > 1);
        }
        return (byte[])list2.get(0);
    }
    
    @Override
    public PartialHashtree[] computePathToRoot(final DigestCalculator digestCalculator, final PartialHashtree partialHashtree, int n) {
        final ArrayList list = new ArrayList();
        byte[] array = ERSUtil.computeNodeHash(digestCalculator, partialHashtree);
        list.add(partialHashtree);
        for (int i = 0; i < this.tree.size() - 1; ++i) {
            if (n == this.tree.get(i).size() - 1) {
                while (true) {
                    final List list2 = this.tree.get(i + 1);
                    if (!Arrays.areEqual(array, (byte[])list2.get(list2.size() - 1))) {
                        break;
                    }
                    ++i;
                    n = this.tree.get(i).size() - 1;
                }
            }
            byte[] array2;
            if ((n & 0x1) == 0x0) {
                array2 = this.tree.get(i).get(n + 1);
            }
            else {
                array2 = this.tree.get(i).get(n - 1);
            }
            list.add(new PartialHashtree(array2));
            array = ERSUtil.calculateBranchHash(digestCalculator, array, array2);
            n /= 2;
        }
        return (PartialHashtree[])list.toArray(new PartialHashtree[0]);
    }
    
    @Override
    public byte[] recoverRootHash(final DigestCalculator digestCalculator, final PartialHashtree[] array) {
        byte[] array2 = ERSUtil.computeNodeHash(digestCalculator, array[0]);
        for (int i = 1; i < array.length; ++i) {
            array2 = ERSUtil.calculateBranchHash(digestCalculator, array2, ERSUtil.computeNodeHash(digestCalculator, array[i]));
        }
        return array2;
    }
}
