/* ====================================================================
   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 org.apache.poi.poifs.storage.BATBlock.BATBlockAndIndex;

/**
 * This abstract class describes a way to read, store, chain
 *  and free a series of blocks (be they Big or Small ones)
 */
public abstract class BlockStore {
   /**
    * Returns the size of the blocks managed through the block store.
    */
   protected abstract int getBlockStoreBlockSize();

    /**
     * Load the block at the given offset.
     */
    protected abstract ByteBuffer getBlockAt(final int offset) throws IOException;

    /**
     * Extends the file if required to hold blocks up to
     *  the specified offset, and return the block from there.
     */
    protected abstract ByteBuffer createBlockIfNeeded(final int offset) throws IOException;

    /**
     * Releases a mmap-ed buffer, which you are sure won't be used again
     * @param buffer the buffer
     */
    protected abstract void releaseBuffer(ByteBuffer buffer);

    /**
     * Returns the BATBlock that handles the specified offset,
     *  and the relative index within it
     */
    protected abstract BATBlockAndIndex getBATBlockAndIndex(final int offset);

    /**
     * Works out what block follows the specified one.
     */
    protected abstract int getNextBlock(final int offset);

    /**
     * Changes the record of what block follows the specified one.
     */
    protected abstract void setNextBlock(final int offset, final int nextBlock);

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

    /**
     * Creates a Detector for loops in the chain
     */
    protected abstract ChainLoopDetector getChainLoopDetector() throws IOException;

    /**
     * Used to detect if a chain has a loop in it, so
     *  we can bail out with an error rather than
     *  spinning away for ever...
     */
    protected class ChainLoopDetector {
       private final boolean[] used_blocks;
       protected ChainLoopDetector(long rawSize) {
          int blkSize = getBlockStoreBlockSize();
          int numBlocks = (int)(rawSize / blkSize);
          if ((rawSize % blkSize) != 0) {
              numBlocks++;
          }
          used_blocks = new boolean[numBlocks];
       }
       protected void claim(int offset) {
          if(offset >= used_blocks.length) {
             // They're writing, and have had new blocks requested
             //  for the write to proceed. That means they're into
             //  blocks we've allocated for them, so are safe
             return;
          }

          // Claiming an existing block, ensure there's no loop
          if(used_blocks[offset]) {
             throw new IllegalStateException(
                   "Potential loop detected - Block " + offset +
                   " was already claimed but was just requested again"
             );
          }
          used_blocks[offset] = true;
       }
    }
}

