/*
 *  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.directory.mavibot.btree;


import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Comparator;
import java.util.UUID;

import org.apache.directory.mavibot.btree.exception.BTreeOperationException;
import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;


/**
 * A holder to store the Values
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @param <V> The value type
 */
/* No qualifier */class InMemoryValueHolder<V> extends AbstractValueHolder<V>
{
    /**
     * Creates a new instance of a ValueHolder, containing the serialized values.
     *
     * @param parentBtree the parent BTree
     * @param valueSerializer The Value's serializer
     * @param raw The raw data containing the values
     * @param nbValues the number of stored values
     * @param raw the byte[] containing either the serialized array of values or the sub-btree offset
     */
    InMemoryValueHolder( BTree<?, V> parentBtree, int nbValues )
    {
        valueSerializer = parentBtree.getValueSerializer();

        if ( nbValues <= 1 )
        {
            valueArray = ( V[] ) Array.newInstance( valueSerializer.getType(), nbValues );
        }
    }


    /**
     * Creates a new instance of a ValueHolder, containing Values. This constructor is called
     * when we need to create a new ValueHolder with deserialized values.
     *
     * @param parentBtree The parent BTree
     * @param values The Values stored in the ValueHolder
     */
    InMemoryValueHolder( BTree<?, V> parentBtree, V... values )
    {
        valueSerializer = parentBtree.getValueSerializer();

        if ( ( values != null ) && ( values.length > 0 ) )
        {
            int nbValues = values.length;

            if ( nbValues == 1 )
            {
                // Store the value
                valueArray = ( V[] ) Array.newInstance( valueSerializer.getType(), nbValues );
                valueArray[0] = values[0];
                nbArrayElems = nbValues;
            }
            else
            {
                // Use a sub btree, now that we have reached the threshold
                createSubTree();

                // Now inject all the values into it
                for ( V value : values )
                {
                    try
                    {
                        valueBtree.insert( value, value );
                    }
                    catch ( IOException e )
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


    /**
     * {@inheritDoc}
     */
    public int size()
    {
        if ( valueBtree != null )
        {
            return ( int ) valueBtree.getNbElems();
        }
        else
        {
            return nbArrayElems;
        }
    }


    /**
     * Create a new Sub-BTree to store the values.
     */
    protected void createSubTree()
    {
        InMemoryBTreeConfiguration<V, V> configuration = new InMemoryBTreeConfiguration<V, V>();
        configuration.setAllowDuplicates( false );
        configuration.setName( UUID.randomUUID().toString() );
        configuration.setKeySerializer( valueSerializer );
        configuration.setValueSerializer( valueSerializer );

        valueBtree = BTreeFactory.createInMemoryBTree( configuration );
    }


    /**
     * Set the subBtree in the ValueHolder
     */
    /* No qualifier*/void setSubBtree( BTree<V, V> subBtree )
    {
        valueBtree = subBtree;
        valueArray = null;
    }


    /**
     * {@inheritDoc}
     */
    public V remove( V value )
    {
        V removedValue = null;

        if ( valueArray != null )
        {
            removedValue = removeFromArray( value );
        }
        else
        {
            removedValue = removeFromBtree( value );
        }

        return removedValue;
    }


    /**
     * Remove the value from a sub btree
     */
    private V removeFromBtree( V removedValue )
    {
        V returnedValue = null;

        try
        {
            Tuple<V, V> removedTuple = valueBtree.delete( removedValue );

            if ( removedTuple != null )
            {
                returnedValue = removedTuple.getKey();
            }
        }
        catch ( IOException e )
        {
            throw new BTreeOperationException( e );
        }

        if ( valueBtree.getNbElems() == 1 )
        {
            try
            {
                valueArray = ( V[] ) Array.newInstance( valueSerializer.getType(), 1 );
                valueArray[0] = valueBtree.browse().next().getKey();
                nbArrayElems = 1;
                valueBtree.close();
                valueBtree = null;
            }
            catch ( EndOfFileExceededException e )
            {
                throw new BTreeOperationException( e );
            }
            catch ( IOException e )
            {
                throw new BTreeOperationException( e );
            }
            catch ( KeyNotFoundException knfe )
            {
                throw new BTreeOperationException( knfe );
            }
        }

        return returnedValue;
    }


    /**
     * Remove a value from an array
     */
    private V removeFromArray( V value )
    {
        // First check that the value is not already present in the ValueHolder
        Comparator<V> comparator = valueSerializer.getComparator();

        int result = comparator.compare( valueArray[0], value );

        if ( result != 0 )
        {
            // The value does not exists : nothing to do
            return null;
        }
        else
        {
            V returnedValue = valueArray[0];
            nbArrayElems = 0;

            return returnedValue;
        }
    }


    /**
     * {@inheritDoc}
     */
    public boolean contains( V checkedValue )
    {
        if ( valueBtree != null )
        {
            try
            {
                return valueBtree.hasKey( checkedValue );
            }
            catch ( IOException e )
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            catch ( KeyNotFoundException knfe )
            {
                // TODO Auto-generated catch block
                knfe.printStackTrace();
                return false;
            }
        }
        else
        {
            Comparator<V> comparator = valueSerializer.getComparator();

            int result = comparator.compare( checkedValue, valueArray[0] );

            return result == 0;
        }
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        sb.append( "ValueHolder[" ).append( valueSerializer.getClass().getSimpleName() );

        if ( valueBtree != null )
        {
            sb.append( ", SubBTree" );
        }
        else
        {
            sb.append( ", {" );

            if ( size() != 0 )
            {
                sb.append( valueArray[0] );
            }

            sb.append( "}" );
        }

        sb.append( "]" );

        return sb.toString();
    }
}
