/*
 *  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.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.directory.mavibot.btree.exception.InitializationException;
import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
import org.apache.directory.mavibot.btree.exception.MissingSerializerException;
import org.apache.directory.mavibot.btree.serializer.BufferHandler;
import org.apache.directory.mavibot.btree.serializer.LongSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * The B+Tree MVCC data structure.
 *
 * @param <K> The type for the keys
 * @param <V> The type for the stored values
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
/* No qualifier */class InMemoryBTree<K, V> extends AbstractBTree<K, V> implements Closeable
{
    /** The LoggerFactory used by this class */
    protected static final Logger LOG = LoggerFactory.getLogger( InMemoryBTree.class );

    /** The default journal name */
    public static final String DEFAULT_JOURNAL = "mavibot.log";

    /** The default data file suffix */
    public static final String DATA_SUFFIX = ".db";

    /** The default journal file suffix */
    public static final String JOURNAL_SUFFIX = ".log";

    /** The type to use to create the keys */
    /** The associated file. If null, this is an in-memory btree  */
    private File file;

    /** A flag used to tell the BTree that the journal is activated */
    private boolean withJournal;

    /** The associated journal. If null, this is an in-memory btree  */
    private File journal;

    /** The directory where the journal will be stored */
    private File envDir;

    /** The Journal channel */
    private FileChannel journalChannel = null;

    /**
     * Creates a new BTree, with no initialization.
     */
    /* no qualifier */InMemoryBTree()
    {
        super();
        setType( BTreeTypeEnum.IN_MEMORY );
    }


    /**
     * Creates a new in-memory BTree using the BTreeConfiguration to initialize the
     * BTree
     *
     * @param configuration The configuration to use
     */
    /* no qualifier */InMemoryBTree( InMemoryBTreeConfiguration<K, V> configuration )
    {
        super();
        String btreeName = configuration.getName();

        if ( btreeName == null )
        {
            throw new IllegalArgumentException( "BTree name cannot be null" );
        }

        String filePath = configuration.getFilePath();

        if ( filePath != null )
        {
            envDir = new File( filePath );
        }

        // Store the configuration in the B-tree
        setName( btreeName );
        setPageSize( configuration.getPageSize() );
        setKeySerializer( configuration.getKeySerializer() );
        setValueSerializer( configuration.getValueSerializer() );
        setAllowDuplicates( configuration.isAllowDuplicates() );
        setType( configuration.getType() );

        readTimeOut = configuration.getReadTimeOut();
        writeBufferSize = configuration.getWriteBufferSize();

        if ( keySerializer.getComparator() == null )
        {
            throw new IllegalArgumentException( "Comparator should not be null" );
        }

        // Create the B-tree header
        BTreeHeader<K, V> newBtreeHeader = new BTreeHeader<K, V>();

        // Create the first root page, with revision 0L. It will be empty
        // and increment the revision at the same time
        newBtreeHeader.setBTreeHeaderOffset( 0L );
        newBtreeHeader.setRevision( 0L );
        newBtreeHeader.setNbElems( 0L );
        newBtreeHeader.setRootPage( new InMemoryLeaf<K, V>( this ) );
        newBtreeHeader.setRootPageOffset( 0L );

        btreeRevisions.put( 0L,  newBtreeHeader );
        currentBtreeHeader = newBtreeHeader;

        // Now, initialize the BTree
        try
        {
            init();
        }
        catch ( IOException ioe )
        {
            throw new InitializationException( ioe.getMessage() );
        }
    }


    /**
     * Initialize the BTree.
     *
     * @throws IOException If we get some exception while initializing the BTree
     */
    private void init() throws IOException
    {
        // if not in-memory then default to persist mode instead of managed
        if ( envDir != null )
        {
            if ( !envDir.exists() )
            {
                boolean created = envDir.mkdirs();

                if ( !created )
                {
                    throw new IllegalStateException( "Could not create the directory " + envDir + " for storing data" );
                }
            }

            this.file = new File( envDir, getName() + DATA_SUFFIX );

            this.journal = new File( envDir, file.getName() + JOURNAL_SUFFIX );
            setType( BTreeTypeEnum.BACKED_ON_DISK );
        }

        // Create the queue containing the pending read transactions
        readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
        
        // Create the transaction manager
        transactionManager = new InMemoryTransactionManager();

        // Check the files and create them if missing
        // Create the queue containing the modifications, if it's not a in-memory btree
        if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
        {
            if ( file.length() > 0 )
            {
                // We have some existing file, load it
                load( file );
            }

            withJournal = true;

            FileOutputStream stream = new FileOutputStream( journal );
            journalChannel = stream.getChannel();

            // If the journal is not empty, we have to read it
            // and to apply all the modifications to the current file
            if ( journal.length() > 0 )
            {
                applyJournal();
            }
        }
        else
        {
            setType( BTreeTypeEnum.IN_MEMORY );

            // This is a new Btree, we have to store the BtreeHeader
            BTreeHeader<K, V> btreeHeader = new BTreeHeader<K, V>();
            btreeHeader.setRootPage( new InMemoryLeaf<K, V>( this ) );
            btreeHeader.setBtree( this );
            storeRevision( btreeHeader );
        }

        // Initialize the txnManager thread
        //FIXME we should NOT create a new transaction manager thread for each BTree
        //createTransactionManager();
    }


    /**
     * {@inheritDoc}
     */
    protected ReadTransaction<K, V> beginReadTransaction()
    {
        BTreeHeader<K, V> btreeHeader = getBtreeHeader();

        ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>( btreeHeader, readTransactions );

        readTransactions.add( readTransaction );

        return readTransaction;
    }
    
    
    /**
     * {@inheritDoc}
     */
    protected ReadTransaction<K, V> beginReadTransaction( long revision )
    {
        BTreeHeader<K, V> btreeHeader = getBtreeHeader( revision );

        if ( btreeHeader != null )
        {
            ReadTransaction<K, V> readTransaction = new ReadTransaction<K, V>(  btreeHeader, readTransactions );

            readTransactions.add( readTransaction );

            return readTransaction;
        }
        else
        {
            return null;
        }
    }


    /**
     * Close the BTree, cleaning up all the data structure
     */
    public void close() throws IOException
    {
        // Stop the readTransaction thread
        // readTransactionsThread.interrupt();
        // readTransactions.clear();

        if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
        {
            // Flush the data
            flush();
            journalChannel.close();
        }
    }


    /**
     *
     * Deletes the given <key,value> pair if both key and value match. If the given value is null
     * and there is no null value associated with the given key then the entry with the given key
     * will be removed.
     *
     * @param key The key to be removed
     * @param value The value to be removed (can be null, and when no null value exists the key will be removed irrespective of the value)
     * @param revision The revision to be associated with this operation
     * @return
     * @throws IOException
     */
    protected Tuple<K, V> delete( K key, V value, long revision ) throws IOException
    {
        if ( revision == -1L )
        {
            revision = currentRevision.get() + 1;
        }

        BTreeHeader<K, V> oldBtreeHeader = getBtreeHeader();
        BTreeHeader<K, V> newBtreeHeader = createNewBtreeHeader( oldBtreeHeader, revision );
        newBtreeHeader.setBtree( this );

        // If the key exists, the existing value will be replaced. We store it
        // to return it to the caller.
        Tuple<K, V> tuple = null;

        // Try to delete the entry starting from the root page. Here, the root
        // page may be either a Node or a Leaf
        DeleteResult<K, V> result = getRootPage().delete( key, value, revision );

        if ( result instanceof NotPresentResult )
        {
            // Key not found.
            return null;
        }

        // Keep the oldRootPage so that we can later access it
        //Page<K, V> oldRootPage = rootPage;

        if ( result instanceof RemoveResult )
        {
            // The element was found, and removed
            RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;

            Page<K, V> modifiedPage = removeResult.getModifiedPage();

            // This is a new root
            newBtreeHeader.setRootPage( modifiedPage );
            tuple = removeResult.getRemovedElement();
        }

        if ( withJournal )
        {
            // Inject the modification into the modification queue
            writeToJournal( new Deletion<K, V>( key ) );
        }

        // Decrease the number of elements in the current tree if the deletion is successful
        if ( tuple != null )
        {
            newBtreeHeader.decrementNbElems();
        }

        storeRevision( newBtreeHeader );

        // Return the value we have found if it was modified
        if ( oldBtreeHeader.getNbUsers() == 0 )
        {
            btreeRevisions.remove( oldBtreeHeader.getRevision() );
        }

        return tuple;
    }


    /**
     * Insert an entry in the BTree.
     * <p>
     * We will replace the value if the provided key already exists in the
     * btree.
     * <p>
     * The revision number is the revision to use to insert the data.
     *
     * @param key Inserted key
     * @param value Inserted value
     * @param revision The revision to use
     * @return an instance of the InsertResult.
     */
    /* no qualifier */InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
    {
        // We have to start a new transaction, which will be committed or rollbacked
        // locally. This will duplicate the current BtreeHeader during this phase.
        if ( revision == -1L )
        {
            revision = currentRevision.get() + 1;
        }

        BTreeHeader<K, V> oldBtreeHeader = getBtreeHeader();
        BTreeHeader<K, V> newBtreeHeader = createNewBtreeHeader( oldBtreeHeader, revision );
        newBtreeHeader.setBtree( this );

        // If the key exists, the existing value will be replaced. We store it
        // to return it to the caller.
        V modifiedValue = null;

        // Try to insert the new value in the tree at the right place,
        // starting from the root page. Here, the root page may be either
        // a Node or a Leaf
        InsertResult<K, V> result = newBtreeHeader.getRootPage().insert( key, value, revision );

        if ( result instanceof ModifyResult )
        {
            ModifyResult<K, V> modifyResult = ( ( ModifyResult<K, V> ) result );

            Page<K, V> modifiedPage = modifyResult.getModifiedPage();

            // The root has just been modified, we haven't split it
            // Get it and make it the current root page
            newBtreeHeader.setRootPage( modifiedPage );

            modifiedValue = modifyResult.getModifiedValue();
        }
        else
        {
            // We have split the old root, create a new one containing
            // only the pivotal we got back
            SplitResult<K, V> splitResult = ( ( SplitResult<K, V> ) result );

            K pivot = splitResult.getPivot();
            Page<K, V> leftPage = splitResult.getLeftPage();
            Page<K, V> rightPage = splitResult.getRightPage();

            // Create the new rootPage
            newBtreeHeader.setRootPage( new InMemoryNode<K, V>( this, revision, pivot, leftPage, rightPage ) );
        }

        // Inject the modification into the modification queue
        if ( withJournal )
        {
            writeToJournal( new Addition<K, V>( key, value ) );
        }

        // Increase the number of element in the current tree if the insertion is successful
        // and does not replace an element
        if ( modifiedValue == null )
        {
            newBtreeHeader.incrementNbElems();
        }

        storeRevision( newBtreeHeader );

        if ( oldBtreeHeader.getNbUsers() == 0 )
        {
            long oldRevision = oldBtreeHeader.getRevision();

            if ( oldRevision < newBtreeHeader.getRevision() )
            {
                btreeRevisions.remove( oldBtreeHeader.getRevision() );
            }
        }

        // Return the value we have found if it was modified
        return result;
    }


    /**
     * Write the data in the ByteBuffer, and eventually on disk if needed.
     *
     * @param channel The channel we want to write to
     * @param bb The ByteBuffer we want to feed
     * @param buffer The data to inject
     * @throws IOException If the write failed
     */
    private void writeBuffer( FileChannel channel, ByteBuffer bb, byte[] buffer ) throws IOException
    {
        int size = buffer.length;
        int pos = 0;

        // Loop until we have written all the data
        do
        {
            if ( bb.remaining() >= size )
            {
                // No flush, as the ByteBuffer is big enough
                bb.put( buffer, pos, size );
                size = 0;
            }
            else
            {
                // Flush the data on disk, reinitialize the ByteBuffer
                int len = bb.remaining();
                size -= len;
                bb.put( buffer, pos, len );
                pos += len;

                bb.flip();

                channel.write( bb );

                bb.clear();
            }
        }
        while ( size > 0 );
    }


    /**
     * Flush the latest revision to disk
     * @param file The file into which the data will be written
     */
    public void flush( File file ) throws IOException
    {
        File parentFile = file.getParentFile();
        File baseDirectory = null;

        if ( parentFile != null )
        {
            baseDirectory = new File( file.getParentFile().getAbsolutePath() );
        }
        else
        {
            baseDirectory = new File( "." );
        }

        // Create a temporary file in the same directory to flush the current btree
        File tmpFileFD = File.createTempFile( "mavibot", null, baseDirectory );
        FileOutputStream stream = new FileOutputStream( tmpFileFD );
        FileChannel ch = stream.getChannel();

        // Create a buffer containing 200 4Kb pages (around 1Mb)
        ByteBuffer bb = ByteBuffer.allocateDirect( writeBufferSize );

        try
        {
            TupleCursor<K, V> cursor = browse();
    
            if ( keySerializer == null )
            {
                throw new MissingSerializerException( "Cannot flush the btree without a Key serializer" );
            }
    
            if ( valueSerializer == null )
            {
                throw new MissingSerializerException( "Cannot flush the btree without a Value serializer" );
            }
    
            // Write the number of elements first
            bb.putLong( getBtreeHeader().getNbElems() );
    
            while ( cursor.hasNext() )
            {
                Tuple<K, V> tuple = cursor.next();
    
                byte[] keyBuffer = keySerializer.serialize( tuple.getKey() );
    
                writeBuffer( ch, bb, keyBuffer );
    
                byte[] valueBuffer = valueSerializer.serialize( tuple.getValue() );
    
                writeBuffer( ch, bb, valueBuffer );
            }
    
            // Write the buffer if needed
            if ( bb.position() > 0 )
            {
                bb.flip();
                ch.write( bb );
            }
    
            // Flush to the disk for real
            ch.force( true );
            ch.close();
        }
        catch ( KeyNotFoundException knfe )
        {
            knfe.printStackTrace();
            throw new IOException( knfe.getMessage() );
        }

        // Rename the current file to save a backup
        File backupFile = File.createTempFile( "mavibot", null, baseDirectory );
        file.renameTo( backupFile );

        // Rename the temporary file to the initial file
        tmpFileFD.renameTo( file );

        // We can now delete the backup file
        backupFile.delete();
    }


    /**
     * Inject all the modification from the journal into the btree
     *
     * @throws IOException If we had some issue while reading the journal
     */
    private void applyJournal() throws IOException
    {
        if ( !journal.exists() )
        {
            throw new IOException( "The journal does not exist" );
        }

        FileChannel channel =
            new RandomAccessFile( journal, "rw" ).getChannel();
        ByteBuffer buffer = ByteBuffer.allocate( 65536 );

        BufferHandler bufferHandler = new BufferHandler( channel, buffer );

        // Loop on all the elements, store them in lists atm
        try
        {
            while ( true )
            {
                // Read the type
                byte[] type = bufferHandler.read( 1 );

                if ( type[0] == Modification.ADDITION )
                {
                    // Read the key
                    K key = keySerializer.deserialize( bufferHandler );

                    //keys.add( key );

                    // Read the value
                    V value = valueSerializer.deserialize( bufferHandler );

                    //values.add( value );

                    // Inject the data in the tree. (to be replaced by a bulk load)
                    insert( key, value, getBtreeHeader().getRevision() );
                }
                else
                {
                    // Read the key
                    K key = keySerializer.deserialize( bufferHandler );

                    // Remove the key from the tree
                    delete( key, getBtreeHeader().getRevision() );
                }
            }
        }
        catch ( EOFException eofe )
        {
            eofe.printStackTrace();
            // Done reading the journal. truncate it
            journalChannel.truncate( 0 );
        }
    }


    /**
     * Read the data from the disk into this BTree. All the existing data in the
     * BTree are kept, the read data will be associated with a new revision.
     *
     * @param file
     * @throws IOException
     */
    public void load( File file ) throws IOException
    {
        if ( !file.exists() )
        {
            throw new IOException( "The file does not exist" );
        }

        FileChannel channel =
            new RandomAccessFile( file, "rw" ).getChannel();
        ByteBuffer buffer = ByteBuffer.allocate( 65536 );

        BufferHandler bufferHandler = new BufferHandler( channel, buffer );

        long nbElems = LongSerializer.deserialize( bufferHandler.read( 8 ) );

        // desactivate the journal while we load the file
        boolean isJournalActivated = withJournal;

        withJournal = false;

        // Loop on all the elements, store them in lists atm
        for ( long i = 0; i < nbElems; i++ )
        {
            // Read the key
            K key = keySerializer.deserialize( bufferHandler );

            // Read the value
            V value = valueSerializer.deserialize( bufferHandler );

            // Inject the data in the tree. (to be replaced by a bulk load)
            insert( key, value, getBtreeHeader().getRevision() );
        }

        // Restore the withJournal value
        withJournal = isJournalActivated;

        // Now, process the lists to create the btree
        // TODO... BulkLoad
    }


    /**
     * Get the rootPage associated to a give revision.
     *
     * @param revision The revision we are looking for
     * @return The rootPage associated to this revision
     * @throws IOException If we had an issue while accessing the underlying file
     * @throws KeyNotFoundException If the revision does not exist for this Btree
     */
    public Page<K, V> getRootPage( long revision ) throws IOException, KeyNotFoundException
    {
        // Atm, the in-memory BTree does not support searches in many revisions
        return getBtreeHeader().getRootPage();
    }


    /**
     * Get the current rootPage
     *
     * @return The rootPage
     */
    public Page<K, V> getRootPage()
    {
        return getBtreeHeader().getRootPage();
    }


    /* no qualifier */void setRootPage( Page<K, V> root )
    {
        getBtreeHeader().setRootPage( root );
    }


    /**
     * Flush the latest revision to disk. We will replace the current file by the new one, as
     * we flush in a temporary file.
     */
    public void flush() throws IOException
    {
        if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
        {
            // Then flush the file
            flush( file );
            journalChannel.truncate( 0 );
        }
    }


    /**
     * @return the file
     */
    public File getFile()
    {
        return file;
    }


    /**
     * @return the journal
     */
    public File getJournal()
    {
        return journal;
    }


    /**
     * @return true if the BTree is fully in memory
     */
    public boolean isInMemory()
    {
        return getType() == BTreeTypeEnum.IN_MEMORY;
    }


    /**
     * @return true if the BTree is persisted on disk
     */
    public boolean isPersistent()
    {
        return getType() == BTreeTypeEnum.IN_MEMORY;
    }


    private void writeToJournal( Modification<K, V> modification )
        throws IOException
    {
        if ( modification instanceof Addition )
        {
            byte[] keyBuffer = keySerializer.serialize( modification.getKey() );
            ByteBuffer bb = ByteBuffer.allocateDirect( keyBuffer.length + 1 );
            bb.put( Modification.ADDITION );
            bb.put( keyBuffer );
            bb.flip();

            journalChannel.write( bb );

            byte[] valueBuffer = valueSerializer.serialize( modification.getValue() );
            bb = ByteBuffer.allocateDirect( valueBuffer.length );
            bb.put( valueBuffer );
            bb.flip();

            journalChannel.write( bb );
        }
        else if ( modification instanceof Deletion )
        {
            byte[] keyBuffer = keySerializer.serialize( modification.getKey() );
            ByteBuffer bb = ByteBuffer.allocateDirect( keyBuffer.length + 1 );
            bb.put( Modification.DELETION );
            bb.put( keyBuffer );
            bb.flip();

            journalChannel.write( bb );
        }

        // Flush to the disk for real
        journalChannel.force( true );
    }


    /**
     * Create a new B-tree header to be used for update operations
     * @param revision The reclaimed revision
     */
    private BTreeHeader<K, V> createNewBtreeHeader( BTreeHeader<K, V> btreeHeader, long revision )
    {
        BTreeHeader<K, V> newBtreeHeader = new BTreeHeader<K, V>();

        newBtreeHeader.setBTreeHeaderOffset( btreeHeader.getBTreeHeaderOffset() );
        newBtreeHeader.setRevision( revision );
        newBtreeHeader.setNbElems( btreeHeader.getNbElems() );
        newBtreeHeader.setRootPage( btreeHeader.getRootPage() );

        return newBtreeHeader;
    }


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

        switch ( getType() )
        {
            case IN_MEMORY:
                sb.append( "In-memory " );
                break;

            case BACKED_ON_DISK:
                sb.append( "Persistent " );
                break;
                
            default :
                sb.append( "Wrong type... " );
                break;
        }

        sb.append( "BTree" );
        sb.append( "[" ).append( getName() ).append( "]" );
        sb.append( "( pageSize:" ).append( getPageSize() );

        if ( getBtreeHeader().getRootPage() != null )
        {
            sb.append( ", nbEntries:" ).append( getBtreeHeader().getNbElems() );
        }
        else
        {
            sb.append( ", nbEntries:" ).append( 0 );
        }

        sb.append( ", comparator:" );

        if ( keySerializer.getComparator() == null )
        {
            sb.append( "null" );
        }
        else
        {
            sb.append( keySerializer.getComparator().getClass().getSimpleName() );
        }

        sb.append( ", DuplicatesAllowed: " ).append( isAllowDuplicates() );

        if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
        {
            try
            {
                sb.append( ", file : " );

                if ( file != null )
                {
                    sb.append( file.getCanonicalPath() );
                }
                else
                {
                    sb.append( "Unknown" );
                }

                sb.append( ", journal : " );

                if ( journal != null )
                {
                    sb.append( journal.getCanonicalPath() );
                }
                else
                {
                    sb.append( "Unkown" );
                }
            }
            catch ( IOException ioe )
            {
                // There is little we can do here...
            }
        }

        sb.append( ") : \n" );
        sb.append( getRootPage().dumpPage( "" ) );

        return sb.toString();
    }
}
