/* ====================================================================
   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) throws IOException {
        // 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);
    }
}
