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

package com.google.crypto.tink.internal;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.crypto.tink.util.Bytes;
import com.google.errorprone.annotations.Immutable;

@Immutable
public final class PrefixMap<P>
{
    private static final Bytes EMPTY_BYTES;
    private final Map<Bytes, List<P>> entries;
    
    public Iterable<P> getAllWithMatchingPrefix(final byte[] text) {
        final List<P> zeroByteEntriesOrNull = this.entries.get(PrefixMap.EMPTY_BYTES);
        final List<P> fiveByteEntriesOrNull = (text.length >= 5) ? this.entries.get(Bytes.copyFrom(text, 0, 5)) : null;
        if (zeroByteEntriesOrNull == null && fiveByteEntriesOrNull == null) {
            return new ArrayList<P>();
        }
        if (zeroByteEntriesOrNull == null) {
            return fiveByteEntriesOrNull;
        }
        if (fiveByteEntriesOrNull == null) {
            return zeroByteEntriesOrNull;
        }
        return new Iterable<P>() {
            @Override
            public Iterator<P> iterator() {
                return new ConcatenatedIterator<P>((Iterator)fiveByteEntriesOrNull.iterator(), (Iterator)zeroByteEntriesOrNull.iterator());
            }
        };
    }
    
    private PrefixMap(final Map<Bytes, List<P>> entries) {
        this.entries = entries;
    }
    
    static {
        EMPTY_BYTES = Bytes.copyFrom(new byte[0]);
    }
    
    public static class Builder<P>
    {
        private final Map<Bytes, List<P>> entries;
        
        public Builder() {
            this.entries = new HashMap<Bytes, List<P>>();
        }
        
        @CanIgnoreReturnValue
        public Builder<P> put(final Bytes prefix, final P primitive) throws GeneralSecurityException {
            if (prefix.size() != 0 && prefix.size() != 5) {
                throw new GeneralSecurityException("PrefixMap only supports 0 and 5 byte prefixes");
            }
            List<P> listForThisPrefix;
            if (this.entries.containsKey(prefix)) {
                listForThisPrefix = this.entries.get(prefix);
            }
            else {
                listForThisPrefix = new ArrayList<P>();
                this.entries.put(prefix, listForThisPrefix);
            }
            listForThisPrefix.add(primitive);
            return this;
        }
        
        public PrefixMap<P> build() {
            return new PrefixMap<P>(this.entries, null);
        }
    }
    
    private static class ConcatenatedIterator<P> implements Iterator<P>
    {
        private final Iterator<P> it0;
        private final Iterator<P> it1;
        
        private ConcatenatedIterator(final Iterator<P> it0, final Iterator<P> it1) {
            this.it0 = it0;
            this.it1 = it1;
        }
        
        @Override
        public boolean hasNext() {
            return this.it0.hasNext() || this.it1.hasNext();
        }
        
        @Override
        public P next() {
            if (this.it0.hasNext()) {
                return this.it0.next();
            }
            return this.it1.next();
        }
    }
}
