/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.flex.abc;

import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

/**
 * Abstract representation of an ABC pool.
 * 
 * @param <T> the type of the Pool's elements. T must implement reasonable
 * hashCode and equals methods. Notably, if it uses identity semantics then you
 * will probably end up with duplicate entries in the constant pool.
 */
public final class Pool<T>
{
    /**
     * Construct a new Pool.
     * 
     * @param default_type - one of HasDefaultZero or NoDefaultZero; the Pool
     * will have a default meaning for its 0th entry if HasDefaultZero is passed
     * in.
     */
    public Pool(DefaultType default_type)
    {
        this.hasDefaultZero = default_type == DefaultType.HasDefaultZero;
    }

    /**
     * The pool's elements mapped to their positions for quicker lookup.
     */
    final Map<T, Integer> refs = new HashMap<T, Integer>();

    /**
     * The Pool's elements in entry order.
     */
    final ArrayList<T> values = new ArrayList<T>();

    /**
     * When set, the pool has a default meaning for its 0th element (which is
     * not present in the pool).
     */
    final boolean hasDefaultZero;

    /**
     * A type-safe flag callers pass to the constructor to indicate whether or
     * not the Pool has a default zero entry.
     */
    public enum DefaultType
    {
        HasDefaultZero, NoDefaultZero
    };

    /**
     * Add an element to the pool if it's not already present.
     * 
     * @param e - the element to add.
     * @return the element's position in the pool.
     */
    public int add(T e)
    {
        int result;

        if (null == e)
        {
            if (this.hasDefaultZero)
                return 0;
            else
                throw new NullPointerException();
        }
        else
        {
            Integer cached_value = refs.get(e);

            if (cached_value != null)
            {
                result = cached_value;
            }
            else
            {
                values.add(e);
                result = size();
                refs.put(e, result);
            }
        }

        return result;
    }

    /**
     * @return the pool's elements in entry order.
     */
    public ArrayList<T> getValues()
    {
        return values;
    }

    /**
     * @param e - the element of interest.
     * @return the element's position in the pool.
     * @throws IllegalArgumentException if the element isn't in the pool.
     */
    public int id(T e)
    {
        if (null == e && this.hasDefaultZero)
            return 0;
        
        Integer result = refs.get(e);
        
        if (result == null)
            throw new IllegalArgumentException("Unknown pool item \"" + e.toString() + "\"");
        
        return result;
    }

    /**
     * @return the size of the pool; this is the size of the elements, plus one
     * if the pool has a default zeroth element.
     */
    public int size()
    {
        return (hasDefaultZero ? 1 : 0) + refs.size();
    }

    /**
     * When the only entry in a pool with a default zero entry is the default
     * zero entry the nominal size of the pool is 0, otherwise the nominal size
     * of the pool is the same as its size.
     * <p>
     * This method is need to compute the pool size to write into the ABC.
     * 
     * @see #size
     * @return The nominal size of the pool.
     */
    public int getNominalSize()
    {
        final int poolSize = size();
        
        if ((hasDefaultZero) && (poolSize == 1))
        {
            assert refs.size() == 0 : "pool collection for pool with default zero entry should be empty when computed pool size is 1";
            return 0;
        }
        
        assert ((!hasDefaultZero) && (poolSize == refs.size())) || ((hasDefaultZero) && (poolSize == (refs.size() + 1))) : "size of pool collection does not match computed size of pool";
        return poolSize;
    }

    @Override
    public String toString()
    {
        return String.valueOf(refs);
    }
}
