/* ====================================================================
   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.poifs.filesystem;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.property.RootProperty;
import org.apache.poi.poifs.storage.BATBlock;
import org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex;
import org.apache.poi.poifs.storage.HeaderBlock;

/**
 * This class handles the MiniStream (small block store)
 * in the NIO case for {@link POIFSFileSystem}
 */
public class POIFSMiniStore extends BlockStore {
    private final POIFSFileSystem _filesystem;
    private POIFSStream _mini_stream;
    private final List<BATBlock> _sbat_blocks;
    private final HeaderBlock _header;
    private final RootProperty _root;

    POIFSMiniStore(POIFSFileSystem filesystem, RootProperty root,
                   List<BATBlock> sbats, HeaderBlock header) {
        this._filesystem = filesystem;
        this._sbat_blocks = sbats;
        this._header = header;
        this._root = root;

        this._mini_stream = new POIFSStream(filesystem, root.getStartBlock());
    }

    /**
     * Load the block at the given offset.
     */
    protected ByteBuffer getBlockAt(final int offset) {
        // Which big block is this?
        int byteOffset = offset * POIFSConstants.SMALL_BLOCK_SIZE;
        int bigBlockNumber = byteOffset / _filesystem.getBigBlockSize();
        int bigBlockOffset = byteOffset % _filesystem.getBigBlockSize();

        // Now locate the data block for it
        Iterator<ByteBuffer> it = _mini_stream.getBlockIterator();
        for (int i = 0; i < bigBlockNumber; i++) {
            it.next();
        }
        ByteBuffer dataBlock = it.next();
        assert (dataBlock != null);

        // Position ourselves, and take a slice
        dataBlock.position(
                dataBlock.position() + bigBlockOffset
        );
        ByteBuffer miniBuffer = dataBlock.slice();
        miniBuffer.limit(POIFSConstants.SMALL_BLOCK_SIZE);
        return miniBuffer;
    }

    /**
     * Load the block, extending the underlying stream if needed
     */
    protected ByteBuffer createBlockIfNeeded(final int offset) throws IOException {
        boolean firstInStore = false;
        if (_mini_stream.getStartBlock() == POIFSConstants.END_OF_CHAIN) {
            firstInStore = true;
        }

        // Try to get it without extending the stream
        if (!firstInStore) {
            try {
                return getBlockAt(offset);
            } catch (NoSuchElementException ignored) {
            }
        }

        // Need to extend the stream
        // TODO Replace this with proper append support
        // For now, do the extending by hand...

        // Ask for another block
        int newBigBlock = _filesystem.getFreeBlock();
        _filesystem.createBlockIfNeeded(newBigBlock);

        // If we are the first block to be allocated, initialise the stream
        if (firstInStore) {
            _filesystem._get_property_table().getRoot().setStartBlock(newBigBlock);
            _mini_stream = new POIFSStream(_filesystem, newBigBlock);
        } else {
            // Tack it onto the end of our chain
            ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
            int block = _mini_stream.getStartBlock();
            while (true) {
                loopDetector.claim(block);
                int next = _filesystem.getNextBlock(block);
                if (next == POIFSConstants.END_OF_CHAIN) {
                    break;
                }
                block = next;
            }
            _filesystem.setNextBlock(block, newBigBlock);
        }

        // This is now the new end
        _filesystem.setNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN);

        // Now try again, to get the real small block
        return createBlockIfNeeded(offset);
    }

    /**
     * Returns the BATBlock that handles the specified offset,
     * and the relative index within it
     */
    protected BATBlockAndIndex getBATBlockAndIndex(final int offset) {
        return BATBlock.getSBATBlockAndIndex(
                offset, _header, _sbat_blocks
        );
    }

    /**
     * Works out what block follows the specified one.
     */
    protected int getNextBlock(final int offset) {
        BATBlockAndIndex bai = getBATBlockAndIndex(offset);
        return bai.getBlock().getValueAt(bai.getIndex());
    }

    /**
     * Changes the record of what block follows the specified one.
     */
    protected void setNextBlock(final int offset, final int nextBlock) {
        BATBlockAndIndex bai = getBATBlockAndIndex(offset);
        bai.getBlock().setValueAt(
                bai.getIndex(), nextBlock
        );
    }

    /**
     * Finds a free block, and returns its offset.
     * This method will extend the file if needed, and if doing
     * so, allocate new FAT blocks to address the extra space.
     */
    protected int getFreeBlock() throws IOException {
        int sectorsPerSBAT = _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock();

        // First up, do we have any spare ones?
        int offset = 0;
        for (BATBlock sbat : _sbat_blocks) {
            // Check this one
            if (sbat.hasFreeSectors()) {
                // Claim one of them and return it
                for (int j = 0; j < sectorsPerSBAT; j++) {
                    int sbatValue = sbat.getValueAt(j);
                    if (sbatValue == POIFSConstants.UNUSED_BLOCK) {
                        // Bingo
                        return offset + j;
                    }
                }
            }

            // Move onto the next SBAT
            offset += sectorsPerSBAT;
        }

        // If we get here, then there aren't any
        //  free sectors in any of the SBATs
        // So, we need to extend the chain and add another

        // Create a new BATBlock
        BATBlock newSBAT = BATBlock.createEmptyBATBlock(_filesystem.getBigBlockSizeDetails(), false);
        int batForSBAT = _filesystem.getFreeBlock();
        newSBAT.setOurBlockIndex(batForSBAT);

        // Are we the first SBAT?
        if (_header.getSBATCount() == 0) {
            // Tell the header that we've got our first SBAT there
            _header.setSBATStart(batForSBAT);
            _header.setSBATBlockCount(1);
        } else {
            // Find the end of the SBAT stream, and add the sbat in there
            ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
            int batOffset = _header.getSBATStart();
            while (true) {
                loopDetector.claim(batOffset);
                int nextBat = _filesystem.getNextBlock(batOffset);
                if (nextBat == POIFSConstants.END_OF_CHAIN) {
                    break;
                }
                batOffset = nextBat;
            }

            // Add it in at the end
            _filesystem.setNextBlock(batOffset, batForSBAT);

            // And update the count
            _header.setSBATBlockCount(
                    _header.getSBATCount() + 1
            );
        }

        // Finish allocating
        _filesystem.setNextBlock(batForSBAT, POIFSConstants.END_OF_CHAIN);
        _sbat_blocks.add(newSBAT);

        // Return our first spot
        return offset;
    }

    @Override
    protected ChainLoopDetector getChainLoopDetector() {
        return new ChainLoopDetector(_root.getSize());
    }

    protected int getBlockStoreBlockSize() {
        return POIFSConstants.SMALL_BLOCK_SIZE;
    }

    /**
     * Writes the SBATs to their backing blocks, and updates
     * the mini-stream size in the properties. Stream size is
     * based on full blocks used, not the data within the streams
     */
    void syncWithDataSource() throws IOException {
        int blocksUsed = 0;
        for (BATBlock sbat : _sbat_blocks) {
            ByteBuffer block = _filesystem.getBlockAt(sbat.getOurBlockIndex());
            sbat.writeData(block);

            if (!sbat.hasFreeSectors()) {
                blocksUsed += _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock();
            } else {
                blocksUsed += sbat.getOccupiedSize();
            }
        }
        // Set the size on the root in terms of the number of SBAT blocks
        // RootProperty.setSize does the sbat -> bytes conversion for us
        _filesystem._get_property_table().getRoot().setSize(blocksUsed);
    }

    @Override
    protected void releaseBuffer(ByteBuffer buffer) {
        _filesystem.releaseBuffer(buffer);
    }
}
