/* ====================================================================
   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.poi.hwpf.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hwpf.model.types.BKFAbstractType;
import org.apache.poi.util.Internal;

import static org.apache.logging.log4j.util.Unbox.box;

@Internal
public class BookmarksTables
{
    private static final Logger LOG = LogManager.getLogger(BookmarksTables.class);

    private PlexOfCps descriptorsFirst = new PlexOfCps( 4 );

    private PlexOfCps descriptorsLim = new PlexOfCps( 0 );

    private List<String> names = new ArrayList<>(0);

    public BookmarksTables( byte[] tableStream, FileInformationBlock fib )
    {
        read( tableStream, fib );
    }

    public void afterDelete( int startCp, int length )
    {
        descriptorsFirst.adjust( startCp, -length );
        descriptorsLim.adjust( startCp, -length );
        for ( int i = 0; i < descriptorsFirst.length(); i++ )
        {
            GenericPropertyNode startNode = descriptorsFirst.getProperty( i );
            GenericPropertyNode endNode = descriptorsLim.getProperty( i );
            if ( startNode.getStart() == endNode.getStart() )
            {
                LOG.atDebug().log("Removing bookmark #{}...", box(i));
                remove( i );
                i--;
                continue;
            }
        }
    }

    public void afterInsert( int startCp, int length )
    {
        descriptorsFirst.adjust( startCp, length );
        descriptorsLim.adjust( startCp - 1, length );
    }

    public int getBookmarksCount()
    {
        return descriptorsFirst.length();
    }

    public GenericPropertyNode getDescriptorFirst( int index )
            throws IndexOutOfBoundsException
    {
        return descriptorsFirst.getProperty( index );
    }

    public int getDescriptorFirstIndex( GenericPropertyNode descriptorFirst )
    {
        // TODO: very non-optimal
        return Arrays.asList( descriptorsFirst.toPropertiesArray() ).indexOf(
                descriptorFirst );
    }

    public GenericPropertyNode getDescriptorLim( int index )
            throws IndexOutOfBoundsException
    {
        return descriptorsLim.getProperty( index );
    }

    public int getDescriptorsFirstCount()
    {
        return descriptorsFirst.length();
    }

    public int getDescriptorsLimCount()
    {
        return descriptorsLim.length();
    }

    public String getName( int index )
    {
        return names.get( index );
    }

    public int getNamesCount()
    {
        return names.size();
    }

    private void read( byte[] tableStream, FileInformationBlock fib )
    {
        int namesStart = fib.getFcSttbfbkmk();
        int namesLength = fib.getLcbSttbfbkmk();

        if ( namesStart != 0 && namesLength != 0 )
            this.names = new ArrayList<>(Arrays.asList(SttbUtils
                    .readSttbfBkmk(tableStream, namesStart)));

        int firstDescriptorsStart = fib.getFcPlcfbkf();
        int firstDescriptorsLength = fib.getLcbPlcfbkf();
        if ( firstDescriptorsStart != 0 && firstDescriptorsLength != 0 )
            descriptorsFirst = new PlexOfCps(tableStream,
                 firstDescriptorsStart, firstDescriptorsLength,
                 BKFAbstractType.getSize() );

        int limDescriptorsStart = fib.getFcPlcfbkl();
        int limDescriptorsLength = fib.getLcbPlcfbkl();
        if ( limDescriptorsStart != 0 && limDescriptorsLength != 0 )
            descriptorsLim = new PlexOfCps( tableStream, limDescriptorsStart,
                    limDescriptorsLength, 0 );
    }

    public void remove( int index )
    {
        descriptorsFirst.remove( index );
        descriptorsLim.remove( index );
        names.remove( index );
    }

    public void setName( int index, String name )
    {
        names.set( index, name );
    }

    public void writePlcfBkmkf( FileInformationBlock fib,
            ByteArrayOutputStream tableStream ) throws IOException
    {
        if ( descriptorsFirst == null || descriptorsFirst.length() == 0 )
        {
            fib.setFcPlcfbkf( 0 );
            fib.setLcbPlcfbkf( 0 );
            return;
        }

        int start = tableStream.size();
        tableStream.write( descriptorsFirst.toByteArray() );
        int end = tableStream.size();

        fib.setFcPlcfbkf( start );
        fib.setLcbPlcfbkf( end - start );
    }

    public void writePlcfBkmkl( FileInformationBlock fib,
            ByteArrayOutputStream tableStream ) throws IOException
    {
        if ( descriptorsLim == null || descriptorsLim.length() == 0 )
        {
            fib.setFcPlcfbkl( 0 );
            fib.setLcbPlcfbkl( 0 );
            return;
        }

        int start = tableStream.size();
        tableStream.write( descriptorsLim.toByteArray() );
        int end = tableStream.size();

        fib.setFcPlcfbkl( start );
        fib.setLcbPlcfbkl( end - start );
    }

    public void writeSttbfBkmk( FileInformationBlock fib,
            ByteArrayOutputStream tableStream ) throws IOException
    {
        if ( names == null || names.isEmpty() )
        {
            fib.setFcSttbfbkmk( 0 );
            fib.setLcbSttbfbkmk( 0 );
            return;
        }

        int start = tableStream.size();
        SttbUtils.writeSttbfBkmk( names.toArray(new String[0]),
                tableStream );
        int end = tableStream.size();

        fib.setFcSttbfbkmk( start );
        fib.setLcbSttbfbkmk( end - start );
    }
}
