/* ====================================================================
   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 static org.apache.poi.poifs.filesystem.TestNPOIFSFileSystem.writeOutAndReadBack;

import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;

import junit.framework.TestCase;

import org.apache.poi.POIDataSamples;
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.storage.BATBlock;

/**
 * Tests {@link NPOIFSStream}
 */
@SuppressWarnings("resource")
public final class TestNPOIFSStream extends TestCase {
   private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance();

   /**
    * Read a single block stream
    */
   public void testReadTinyStream() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));

      // 98 is actually the last block in a two block stream...
      NPOIFSStream stream = new NPOIFSStream(fs, 98);
      Iterator<ByteBuffer> i = stream.getBlockIterator();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b = i.next();
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      
      // Check the contents
      assertEquals((byte)0x81, b.get());
      assertEquals((byte)0x00, b.get());
      assertEquals((byte)0x00, b.get());
      assertEquals((byte)0x00, b.get());
      assertEquals((byte)0x82, b.get());
      assertEquals((byte)0x00, b.get());
      assertEquals((byte)0x00, b.get());
      assertEquals((byte)0x00, b.get());
      
      fs.close();
   }

   /**
    * Read a stream with only two blocks in it 
    */
   public void testReadShortStream() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      
      // 97 -> 98 -> end
      NPOIFSStream stream = new NPOIFSStream(fs, 97);
      Iterator<ByteBuffer> i = stream.getBlockIterator();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b97 = i.next();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b98 = i.next();
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      
      // Check the contents of the 1st block
      assertEquals((byte)0x01, b97.get());
      assertEquals((byte)0x00, b97.get());
      assertEquals((byte)0x00, b97.get());
      assertEquals((byte)0x00, b97.get());
      assertEquals((byte)0x02, b97.get());
      assertEquals((byte)0x00, b97.get());
      assertEquals((byte)0x00, b97.get());
      assertEquals((byte)0x00, b97.get());
      
      // Check the contents of the 2nd block
      assertEquals((byte)0x81, b98.get());
      assertEquals((byte)0x00, b98.get());
      assertEquals((byte)0x00, b98.get());
      assertEquals((byte)0x00, b98.get());
      assertEquals((byte)0x82, b98.get());
      assertEquals((byte)0x00, b98.get());
      assertEquals((byte)0x00, b98.get());
      assertEquals((byte)0x00, b98.get());
      
      fs.close();
   }
   
   /**
    * Read a stream with many blocks 
    */
   public void testReadLongerStream() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      
      ByteBuffer b0 = null;
      ByteBuffer b1 = null;
      ByteBuffer b22 = null;
      
      // The stream at 0 has 23 blocks in it
      NPOIFSStream stream = new NPOIFSStream(fs, 0);
      Iterator<ByteBuffer> i = stream.getBlockIterator();
      int count = 0;
      while(i.hasNext()) {
         ByteBuffer b = i.next();
         if(count == 0) {
            b0 = b;
         }
         if(count == 1) {
            b1 = b;
         }
         if(count == 22) {
            b22 = b;
         }
         
         count++;
      }
      assertEquals(23, count);
      
      // Check the contents
      //  1st block is at 0
      assertEquals((byte)0x9e, b0.get());
      assertEquals((byte)0x75, b0.get());
      assertEquals((byte)0x97, b0.get());
      assertEquals((byte)0xf6, b0.get());
            
      //  2nd block is at 1
      assertEquals((byte)0x86, b1.get());
      assertEquals((byte)0x09, b1.get());
      assertEquals((byte)0x22, b1.get());
      assertEquals((byte)0xfb, b1.get());
      
      //  last block is at 89
      assertEquals((byte)0xfe, b22.get());
      assertEquals((byte)0xff, b22.get());
      assertEquals((byte)0x00, b22.get());
      assertEquals((byte)0x00, b22.get());
      assertEquals((byte)0x05, b22.get());
      assertEquals((byte)0x01, b22.get());
      assertEquals((byte)0x02, b22.get());
      assertEquals((byte)0x00, b22.get());
      
      fs.close();
   }

   /**
    * Read a stream with several blocks in a 4096 byte block file 
    */
   public void testReadStream4096() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
      
      // 0 -> 1 -> 2 -> end
      NPOIFSStream stream = new NPOIFSStream(fs, 0);
      Iterator<ByteBuffer> i = stream.getBlockIterator();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b0 = i.next();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b1 = i.next();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b2 = i.next();
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      
      // Check the contents of the 1st block
      assertEquals((byte)0x9E, b0.get());
      assertEquals((byte)0x75, b0.get());
      assertEquals((byte)0x97, b0.get());
      assertEquals((byte)0xF6, b0.get());
      assertEquals((byte)0xFF, b0.get());
      assertEquals((byte)0x21, b0.get());
      assertEquals((byte)0xD2, b0.get());
      assertEquals((byte)0x11, b0.get());
      
      // Check the contents of the 2nd block
      assertEquals((byte)0x00, b1.get());
      assertEquals((byte)0x00, b1.get());
      assertEquals((byte)0x03, b1.get());
      assertEquals((byte)0x00, b1.get());
      assertEquals((byte)0x00, b1.get());
      assertEquals((byte)0x00, b1.get());
      assertEquals((byte)0x00, b1.get());
      assertEquals((byte)0x00, b1.get());
      
      // Check the contents of the 3rd block
      assertEquals((byte)0x6D, b2.get());
      assertEquals((byte)0x00, b2.get());
      assertEquals((byte)0x00, b2.get());
      assertEquals((byte)0x00, b2.get());
      assertEquals((byte)0x03, b2.get());
      assertEquals((byte)0x00, b2.get());
      assertEquals((byte)0x46, b2.get());
      assertEquals((byte)0x00, b2.get());
      
      fs.close();
   }
   
   /**
    * Craft a nasty file with a loop, and ensure we don't get stuck
    */
   public void testReadFailsOnLoop() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      
      // Hack the FAT so that it goes 0->1->2->0
      fs.setNextBlock(0, 1);
      fs.setNextBlock(1, 2);
      fs.setNextBlock(2, 0);
      
      // Now try to read
      NPOIFSStream stream = new NPOIFSStream(fs, 0);
      Iterator<ByteBuffer> i = stream.getBlockIterator();
      assertEquals(true, i.hasNext());
      
      // 1st read works
      i.next();
      assertEquals(true, i.hasNext());
      
      // 2nd read works
      i.next();
      assertEquals(true, i.hasNext());
      
      // 3rd read works
      i.next();
      assertEquals(true, i.hasNext());
      
      // 4th read blows up as it loops back to 0
      try {
         i.next();
         fail("Loop should have been detected but wasn't!");
      } catch(RuntimeException e) {
         // Good, it was detected
      }
      assertEquals(true, i.hasNext());
      
      fs.close();
   }

   /**
    * Tests that we can load some streams that are
    *  stored in the mini stream.
    */
   public void testReadMiniStreams() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      NPOIFSMiniStore ministore = fs.getMiniStore();
      
      // 178 -> 179 -> 180 -> end
      NPOIFSStream stream = new NPOIFSStream(ministore, 178);
      Iterator<ByteBuffer> i = stream.getBlockIterator();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b178 = i.next();
      assertEquals(true, i.hasNext());
      assertEquals(true, i.hasNext());
      ByteBuffer b179 = i.next();
      assertEquals(true, i.hasNext());
      ByteBuffer b180 = i.next();
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      assertEquals(false, i.hasNext());
      
      // Check the contents of the 1st block
      assertEquals((byte)0xfe, b178.get());
      assertEquals((byte)0xff, b178.get());
      assertEquals((byte)0x00, b178.get());
      assertEquals((byte)0x00, b178.get());
      assertEquals((byte)0x05, b178.get());
      assertEquals((byte)0x01, b178.get());
      assertEquals((byte)0x02, b178.get());
      assertEquals((byte)0x00, b178.get());
      
      // And the 2nd
      assertEquals((byte)0x6c, b179.get());
      assertEquals((byte)0x00, b179.get());
      assertEquals((byte)0x00, b179.get());
      assertEquals((byte)0x00, b179.get());
      assertEquals((byte)0x28, b179.get());
      assertEquals((byte)0x00, b179.get());
      assertEquals((byte)0x00, b179.get());
      assertEquals((byte)0x00, b179.get());
      
      // And the 3rd
      assertEquals((byte)0x30, b180.get());
      assertEquals((byte)0x00, b180.get());
      assertEquals((byte)0x00, b180.get());
      assertEquals((byte)0x00, b180.get());
      assertEquals((byte)0x00, b180.get());
      assertEquals((byte)0x00, b180.get());
      assertEquals((byte)0x00, b180.get());
      assertEquals((byte)0x80, b180.get());
      
      fs.close();
   }

   /**
    * Writing the same amount of data as before
    */
   public void testReplaceStream() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      
      byte[] data = new byte[512];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      
      // 98 is actually the last block in a two block stream...
      NPOIFSStream stream = new NPOIFSStream(fs, 98);
      stream.updateContents(data);
      
      // Check the reading of blocks
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      assertEquals(true, it.hasNext());
      ByteBuffer b = it.next();
      assertEquals(false, it.hasNext());
      
      // Now check the contents
      data = new byte[512];
      b.get(data);
      for(int i=0; i<data.length; i++) {
         byte exp = (byte)(i%256);
         assertEquals(exp, data[i]);
      }
      
      fs.close();
   }
   
   /**
    * Writes less data than before, some blocks will need
    *  to be freed
    */
   public void testReplaceStreamWithLess() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      
      byte[] data = new byte[512];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      
      // 97 -> 98 -> end
      assertEquals(98, fs.getNextBlock(97));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98));
      
      // Create a 2 block stream, will become a 1 block one
      NPOIFSStream stream = new NPOIFSStream(fs, 97);
      stream.updateContents(data);
      
      // 97 should now be the end, and 98 free
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(97));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(98));
      
      // Check the reading of blocks
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      assertEquals(true, it.hasNext());
      ByteBuffer b = it.next();
      assertEquals(false, it.hasNext());
      
      // Now check the contents
      data = new byte[512];
      b.get(data);
      for(int i=0; i<data.length; i++) {
         byte exp = (byte)(i%256);
         assertEquals(exp, data[i]);
      }
      
      fs.close();
   }
   
   /**
    * Writes more data than before, new blocks will be needed
    */
   public void testReplaceStreamWithMore() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      
      byte[] data = new byte[512*3];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      
      // 97 -> 98 -> end
      assertEquals(98, fs.getNextBlock(97));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(98));
      
      // 100 is our first free one
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
      
      // Create a 2 block stream, will become a 3 block one
      NPOIFSStream stream = new NPOIFSStream(fs, 97);
      stream.updateContents(data);
      
      // 97 -> 98 -> 100 -> end
      assertEquals(98, fs.getNextBlock(97));
      assertEquals(100, fs.getNextBlock(98));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
      
      // Check the reading of blocks
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      int count = 0;
      while(it.hasNext()) {
         ByteBuffer b = it.next();
         data = new byte[512];
         b.get(data);
         for(int i=0; i<data.length; i++) {
            byte exp = (byte)(i%256);
            assertEquals(exp, data[i]);
         }
         count++;
      }
      assertEquals(3, count);
      
      fs.close();
   }
   
   /**
    * Writes to a new stream in the file
    */
   public void testWriteNewStream() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      
      // 100 is our first free one
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
      
      
      // Add a single block one
      byte[] data = new byte[512];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      
      NPOIFSStream stream = new NPOIFSStream(fs);
      stream.updateContents(data);
      
      // Check it was allocated properly
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
      
      // And check the contents
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      int count = 0;
      while(it.hasNext()) {
         ByteBuffer b = it.next();
         data = new byte[512];
         b.get(data);
         for(int i=0; i<data.length; i++) {
            byte exp = (byte)(i%256);
            assertEquals(exp, data[i]);
         }
         count++;
      }
      assertEquals(1, count);
      
      
      // And a multi block one
      data = new byte[512*3];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      
      stream = new NPOIFSStream(fs);
      stream.updateContents(data);
      
      // Check it was allocated properly
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
      assertEquals(102,                         fs.getNextBlock(101));
      assertEquals(103,                         fs.getNextBlock(102));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(103));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
      
      // And check the contents
      it = stream.getBlockIterator();
      count = 0;
      while(it.hasNext()) {
         ByteBuffer b = it.next();
         data = new byte[512];
         b.get(data);
         for(int i=0; i<data.length; i++) {
            byte exp = (byte)(i%256);
            assertEquals(exp, data[i]);
         }
         count++;
      }
      assertEquals(3, count);
      
      // Free it
      stream.free();
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
      
      fs.close();
   }
   
   /**
    * Writes to a new stream in the file, where we've not enough
    *  free blocks so new FAT segments will need to be allocated
    *  to support this
    */
   public void testWriteNewStreamExtraFATs() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      
      // Allocate almost all the blocks
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127));
      for(int i=100; i<127; i++) {
         fs.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
      }
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127));
      assertEquals(true, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());

      
      // Write a 3 block stream
      byte[] data = new byte[512*3];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      NPOIFSStream stream = new NPOIFSStream(fs);
      stream.updateContents(data);
      
      // Check we got another BAT
      assertEquals(false, fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
      assertEquals(true,  fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
      
      // the BAT will be in the first spot of the new block
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(126));
      assertEquals(129,                         fs.getNextBlock(127));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128));
      assertEquals(130,                         fs.getNextBlock(129));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(130));
      assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(131));
      
      fs.close();
   }
   
   /**
    * Replaces data in an existing stream, with a bit
    *  more data than before, in a 4096 byte block file
    */
   public void testWriteStream4096() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
      
      // 0 -> 1 -> 2 -> end
      assertEquals(1, fs.getNextBlock(0));
      assertEquals(2, fs.getNextBlock(1));
      assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
      assertEquals(4, fs.getNextBlock(3));
      
      // First free one is at 15
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14));
      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(15));
      
      
      // Write a 5 block file 
      byte[] data = new byte[4096*5];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i%256);
      }
      NPOIFSStream stream = new NPOIFSStream(fs, 0);
      stream.updateContents(data);
      
      
      // Check it
      assertEquals(1, fs.getNextBlock(0));
      assertEquals(2, fs.getNextBlock(1));
      assertEquals(15, fs.getNextBlock(2)); // Jumps
      assertEquals(4, fs.getNextBlock(3));  // Next stream
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14));
      assertEquals(16,                              fs.getNextBlock(15)); // Continues
      assertEquals(POIFSConstants.END_OF_CHAIN,     fs.getNextBlock(16)); // Ends
      assertEquals(POIFSConstants.UNUSED_BLOCK,     fs.getNextBlock(17)); // Free

      // Check the contents too
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      int count = 0;
      while(it.hasNext()) {
         ByteBuffer b = it.next();
         data = new byte[512];
         b.get(data);
         for(int i=0; i<data.length; i++) {
            byte exp = (byte)(i%256);
            assertEquals(exp, data[i]);
         }
         count++;
      }
      assertEquals(5, count);
      
      fs.close();
   }
   
   /**
    * Tests that we can write into the mini stream
    */
   public void testWriteMiniStreams() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
      NPOIFSMiniStore ministore = fs.getMiniStore();
      NPOIFSStream stream = new NPOIFSStream(ministore, 178);
      
      // 178 -> 179 -> 180 -> end
      assertEquals(179, ministore.getNextBlock(178));
      assertEquals(180, ministore.getNextBlock(179));
      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180));
      
      
      // Try writing 3 full blocks worth
      byte[] data = new byte[64*3];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)i;
      }
      stream = new NPOIFSStream(ministore, 178);
      stream.updateContents(data);
      
      // Check
      assertEquals(179, ministore.getNextBlock(178));
      assertEquals(180, ministore.getNextBlock(179));
      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180));
      
      stream = new NPOIFSStream(ministore, 178);
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      ByteBuffer b178 = it.next();
      ByteBuffer b179 = it.next();
      ByteBuffer b180 = it.next();
      assertEquals(false, it.hasNext());
      
      assertEquals((byte)0x00, b178.get());
      assertEquals((byte)0x01, b178.get());
      assertEquals((byte)0x40, b179.get());
      assertEquals((byte)0x41, b179.get());
      assertEquals((byte)0x80, b180.get());
      assertEquals((byte)0x81, b180.get());

      
      // Try writing just into 3 blocks worth
      data = new byte[64*2 + 12];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i+4);
      }
      stream = new NPOIFSStream(ministore, 178);
      stream.updateContents(data);
      
      // Check
      assertEquals(179, ministore.getNextBlock(178));
      assertEquals(180, ministore.getNextBlock(179));
      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180));
      
      stream = new NPOIFSStream(ministore, 178);
      it = stream.getBlockIterator();
      b178 = it.next();
      b179 = it.next();
      b180 = it.next();
      assertEquals(false, it.hasNext());
      
      assertEquals((byte)0x04, b178.get(0));
      assertEquals((byte)0x05, b178.get(1));
      assertEquals((byte)0x44, b179.get(0));
      assertEquals((byte)0x45, b179.get(1));
      assertEquals((byte)0x84, b180.get(0));
      assertEquals((byte)0x85, b180.get(1));

      
      // Try writing 1, should truncate
      data = new byte[12];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i+9);
      }
      stream = new NPOIFSStream(ministore, 178);
      stream.updateContents(data);

      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(178));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(179));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(180));
      
      stream = new NPOIFSStream(ministore, 178);
      it = stream.getBlockIterator();
      b178 = it.next();
      assertEquals(false, it.hasNext());
      
      assertEquals((byte)0x09, b178.get(0));
      assertEquals((byte)0x0a, b178.get(1));

      
      // Try writing 5, should extend
      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(178));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(179));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(180));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(181));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(182));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(183));
      
      data = new byte[64*4 + 12];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i+3);
      }
      stream = new NPOIFSStream(ministore, 178);
      stream.updateContents(data);
      
      assertEquals(179, ministore.getNextBlock(178));
      assertEquals(180, ministore.getNextBlock(179));
      assertEquals(181, ministore.getNextBlock(180));
      assertEquals(182, ministore.getNextBlock(181));
      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(182));
      
      stream = new NPOIFSStream(ministore, 178);
      it = stream.getBlockIterator();
      b178 = it.next();
      b179 = it.next();
      b180 = it.next();
      ByteBuffer b181 = it.next();
      ByteBuffer b182 = it.next();
      assertEquals(false, it.hasNext());
      
      assertEquals((byte)0x03, b178.get(0));
      assertEquals((byte)0x04, b178.get(1));
      assertEquals((byte)0x43, b179.get(0));
      assertEquals((byte)0x44, b179.get(1));
      assertEquals((byte)0x83, b180.get(0));
      assertEquals((byte)0x84, b180.get(1));
      assertEquals((byte)0xc3, b181.get(0));
      assertEquals((byte)0xc4, b181.get(1));
      assertEquals((byte)0x03, b182.get(0));
      assertEquals((byte)0x04, b182.get(1));

      
      // Write lots, so it needs another big block
      ministore.getBlockAt(183);
      try {
         ministore.getBlockAt(184);
         fail("Block 184 should be off the end of the list");
      } catch(IndexOutOfBoundsException e) {}
      
      data = new byte[64*6 + 12];
      for(int i=0; i<data.length; i++) {
         data[i] = (byte)(i+1);
      }
      stream = new NPOIFSStream(ministore, 178);
      stream.updateContents(data);
      
      // Should have added 2 more blocks to the chain
      assertEquals(179, ministore.getNextBlock(178));
      assertEquals(180, ministore.getNextBlock(179));
      assertEquals(181, ministore.getNextBlock(180));
      assertEquals(182, ministore.getNextBlock(181));
      assertEquals(183, ministore.getNextBlock(182));
      assertEquals(184, ministore.getNextBlock(183));
      assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(184));
      assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(185));
      
      // Block 184 should exist
      ministore.getBlockAt(183);
      ministore.getBlockAt(184);
      ministore.getBlockAt(185);
      
      // Check contents
      stream = new NPOIFSStream(ministore, 178);
      it = stream.getBlockIterator();
      b178 = it.next();
      b179 = it.next();
      b180 = it.next();
      b181 = it.next();
      b182 = it.next();
      ByteBuffer b183 = it.next();
      ByteBuffer b184 = it.next();
      assertEquals(false, it.hasNext());
      
      assertEquals((byte)0x01, b178.get(0));
      assertEquals((byte)0x02, b178.get(1));
      assertEquals((byte)0x41, b179.get(0));
      assertEquals((byte)0x42, b179.get(1));
      assertEquals((byte)0x81, b180.get(0));
      assertEquals((byte)0x82, b180.get(1));
      assertEquals((byte)0xc1, b181.get(0));
      assertEquals((byte)0xc2, b181.get(1));
      assertEquals((byte)0x01, b182.get(0));
      assertEquals((byte)0x02, b182.get(1));
      assertEquals((byte)0x41, b183.get(0));
      assertEquals((byte)0x42, b183.get(1));
      assertEquals((byte)0x81, b184.get(0));
      assertEquals((byte)0x82, b184.get(1));
      
      fs.close();
   }

   /**
    * Craft a nasty file with a loop, and ensure we don't get stuck
    */
   public void testWriteFailsOnLoop() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
      
      // Hack the FAT so that it goes 0->1->2->0
      fs.setNextBlock(0, 1);
      fs.setNextBlock(1, 2);
      fs.setNextBlock(2, 0);
      
      // Try to write a large amount, should fail on the write
      byte[] data = new byte[512*4];
      NPOIFSStream stream = new NPOIFSStream(fs, 0);
      try {
         stream.updateContents(data);
         fail("Loop should have been detected but wasn't!");
      } catch(IllegalStateException e) {}
      
      // Now reset, and try on a small bit
      // Should fail during the freeing set
      fs.setNextBlock(0, 1);
      fs.setNextBlock(1, 2);
      fs.setNextBlock(2, 0);
      
      data = new byte[512];
      stream = new NPOIFSStream(fs, 0);
      try {
         stream.updateContents(data);
         fail("Loop should have been detected but wasn't!");
      } catch(IllegalStateException e) {}
      
      fs.close();
   }
   
   /**
    * Tests adding a new stream, writing and reading it.
    */
   public void testReadWriteNewStream() throws Exception {
      NPOIFSFileSystem fs = new NPOIFSFileSystem();
      NPOIFSStream stream = new NPOIFSStream(fs);
      
      // Check our filesystem has Properties then BAT
      assertEquals(2, fs.getFreeBlock());
      BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
      assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
      assertEquals(POIFSConstants.UNUSED_BLOCK,    bat.getValueAt(2));
      
      // Check the stream as-is
      assertEquals(POIFSConstants.END_OF_CHAIN, stream.getStartBlock());
      try {
         stream.getBlockIterator();
         fail("Shouldn't be able to get an iterator before writing");
      } catch(IllegalStateException e) {}
      
      // Write in two blocks
      byte[] data = new byte[512+20];
      for(int i=0; i<512; i++) {
         data[i] = (byte)(i%256);
      }
      for(int i=512; i<data.length; i++) {
         data[i] = (byte)(i%256 + 100);
      }
      stream.updateContents(data);
      
      // Check now
      assertEquals(4, fs.getFreeBlock());
      bat = fs.getBATBlockAndIndex(0).getBlock();
      assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(0));
      assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
      assertEquals(3,                              bat.getValueAt(2));
      assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(3));
      assertEquals(POIFSConstants.UNUSED_BLOCK,    bat.getValueAt(4));
      
      
      Iterator<ByteBuffer> it = stream.getBlockIterator();
      assertEquals(true, it.hasNext());
      ByteBuffer b = it.next();
      
      byte[] read = new byte[512];
      b.get(read);
      for(int i=0; i<read.length; i++) {
         assertEquals("Wrong value at " + i, data[i], read[i]);
      }
      
      assertEquals(true, it.hasNext());
      b = it.next();
      
      read = new byte[512];
      b.get(read);
      for(int i=0; i<20; i++) {
         assertEquals(data[i+512], read[i]);
      }
      for(int i=20; i<read.length; i++) {
         assertEquals(0, read[i]);
      }
      
      assertEquals(false, it.hasNext());
      
      fs.close();
   }
   
   /**
    * Writes a stream, then replaces it
    */
   public void testWriteThenReplace() throws Exception {
       NPOIFSFileSystem fs = new NPOIFSFileSystem();

       // Starts empty, other that Properties and BAT
       BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
       assertEquals(POIFSConstants.END_OF_CHAIN,    bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
       assertEquals(POIFSConstants.UNUSED_BLOCK,    bat.getValueAt(2));

       // Write something that uses a main stream
       byte[] main4106 = new byte[4106];
       main4106[0] = -10;
       main4106[4105] = -11;
       DocumentEntry normal = fs.getRoot().createDocument(
               "Normal", new ByteArrayInputStream(main4106));
       
       // Should have used 9 blocks
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
       assertEquals(3,                           bat.getValueAt(2));
       assertEquals(4,                           bat.getValueAt(3));
       assertEquals(5,                           bat.getValueAt(4));
       assertEquals(6,                           bat.getValueAt(5));
       assertEquals(7,                           bat.getValueAt(6));
       assertEquals(8,                           bat.getValueAt(7));
       assertEquals(9,                           bat.getValueAt(8));
       assertEquals(10,                          bat.getValueAt(9));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
       
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(4106, normal.getSize());
       assertEquals(4106, ((DocumentNode)normal).getProperty().getSize());

       
       // Replace with one still big enough for a main stream, but one block smaller
       byte[] main4096 = new byte[4096];
       main4096[0] = -10;
       main4096[4095] = -11;
       
       NDocumentOutputStream nout = new NDocumentOutputStream(normal);
       nout.write(main4096);
       nout.close();
       
       // Will have dropped to 8
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
       assertEquals(3,                           bat.getValueAt(2));
       assertEquals(4,                           bat.getValueAt(3));
       assertEquals(5,                           bat.getValueAt(4));
       assertEquals(6,                           bat.getValueAt(5));
       assertEquals(7,                           bat.getValueAt(6));
       assertEquals(8,                           bat.getValueAt(7));
       assertEquals(9,                           bat.getValueAt(8));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));

       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(4096, normal.getSize());
       assertEquals(4096, ((DocumentNode)normal).getProperty().getSize());
       
       
       // Write and check
       fs = writeOutAndReadBack(fs);
       bat = fs.getBATBlockAndIndex(0).getBlock();
       
       // No change after write
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); // Properties
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
       assertEquals(3,                           bat.getValueAt(2));
       assertEquals(4,                           bat.getValueAt(3));
       assertEquals(5,                           bat.getValueAt(4));
       assertEquals(6,                           bat.getValueAt(5));
       assertEquals(7,                           bat.getValueAt(6));
       assertEquals(8,                           bat.getValueAt(7));
       assertEquals(9,                           bat.getValueAt(8));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9)); // End of Normal
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
       
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(4096, normal.getSize());
       assertEquals(4096, ((DocumentNode)normal).getProperty().getSize());
       
       
       // Make longer, take 1 block at the end
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       nout = new NDocumentOutputStream(normal);
       nout.write(main4106);
       nout.close();

       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,bat.getValueAt(1));
       assertEquals(3,                           bat.getValueAt(2));
       assertEquals(4,                           bat.getValueAt(3));
       assertEquals(5,                           bat.getValueAt(4));
       assertEquals(6,                           bat.getValueAt(5));
       assertEquals(7,                           bat.getValueAt(6));
       assertEquals(8,                           bat.getValueAt(7));
       assertEquals(9,                           bat.getValueAt(8));
       assertEquals(10,                          bat.getValueAt(9));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Normal
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
       
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(4106, normal.getSize());
       assertEquals(4106, ((DocumentNode)normal).getProperty().getSize());

       
       // Make it small, will trigger the SBAT stream and free lots up
       byte[] mini = new byte[] { 42, 0, 1, 2, 3, 4, 42 };
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       nout = new NDocumentOutputStream(normal);
       nout.write(mini);
       nout.close();
       
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(5));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(6));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(7));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(8));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(9));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
       
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(7, normal.getSize());
       assertEquals(7, ((DocumentNode)normal).getProperty().getSize());

       
       // Finally back to big again
       nout = new NDocumentOutputStream(normal);
       nout.write(main4096);
       nout.close();
       
       // Will keep the mini stream, now empty
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
       assertEquals(5,                           bat.getValueAt(4));
       assertEquals(6,                           bat.getValueAt(5));
       assertEquals(7,                           bat.getValueAt(6));
       assertEquals(8,                           bat.getValueAt(7));
       assertEquals(9,                           bat.getValueAt(8));
       assertEquals(10,                          bat.getValueAt(9));
       assertEquals(11,                          bat.getValueAt(10));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
       
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(4096, normal.getSize());
       assertEquals(4096, ((DocumentNode)normal).getProperty().getSize());
       
       
       // Save, re-load, re-check
       fs = writeOutAndReadBack(fs);
       bat = fs.getBATBlockAndIndex(0).getBlock();
       
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
       assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
       assertEquals(5,                           bat.getValueAt(4));
       assertEquals(6,                           bat.getValueAt(5));
       assertEquals(7,                           bat.getValueAt(6));
       assertEquals(8,                           bat.getValueAt(7));
       assertEquals(9,                           bat.getValueAt(8));
       assertEquals(10,                          bat.getValueAt(9));
       assertEquals(11,                          bat.getValueAt(10));
       assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
       assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
       
       normal = (DocumentEntry)fs.getRoot().getEntry("Normal");
       assertEquals(4096, normal.getSize());
       assertEquals(4096, ((DocumentNode)normal).getProperty().getSize());
       
       fs.close();
   }
}
