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

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.poifs.common.POIFSBigBlockSize;
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.poifs.filesystem.NPOIFSStream;
import org.apache.poi.poifs.storage.HeaderBlock;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

/**
 * This class embodies the Property Table for a {@link NPOIFSFileSystem}; 
 *  this is basically the directory for all of the documents in the
 * filesystem.
 */
public final class NPropertyTable extends PropertyTableBase {
    private static final POILogger _logger =
       POILogFactory.getLogger(NPropertyTable.class);
    private POIFSBigBlockSize _bigBigBlockSize;

    public NPropertyTable(HeaderBlock headerBlock)
    {
        super(headerBlock);
        _bigBigBlockSize = headerBlock.getBigBlockSize();
    }

    /**
     * reading constructor (used when we've read in a file and we want
     * to extract the property table from it). Populates the
     * properties thoroughly
     *
     * @param headerBlock the header block of the file
     * @param filesystem the filesystem to read from
     *
     * @exception IOException if anything goes wrong (which should be
     *            a result of the input being NFG)
     */
    public NPropertyTable(final HeaderBlock headerBlock,
                          final NPOIFSFileSystem filesystem)
        throws IOException
    {
        super(
              headerBlock,
              buildProperties(
                    (new NPOIFSStream(filesystem, headerBlock.getPropertyStart())).iterator(),
                    headerBlock.getBigBlockSize()
              )
        );
        _bigBigBlockSize = headerBlock.getBigBlockSize();
    }
    
    private static List<Property> buildProperties(final Iterator<ByteBuffer> dataSource,
          final POIFSBigBlockSize bigBlockSize) throws IOException
    {
       List<Property> properties = new ArrayList<Property>();
       while(dataSource.hasNext()) {
          ByteBuffer bb = dataSource.next();
          
          // Turn it into an array
          byte[] data;
          if(bb.hasArray() && bb.arrayOffset() == 0 && 
                bb.array().length == bigBlockSize.getBigBlockSize()) {
             data = bb.array();
          } else {
             data = new byte[bigBlockSize.getBigBlockSize()];
             
             int toRead = data.length;
             if (bb.remaining() < bigBlockSize.getBigBlockSize()) {
                // Looks to be a truncated block
                // This isn't allowed, but some third party created files
                //  sometimes do this, and we can normally read anyway
                _logger.log(POILogger.WARN, "Short Property Block, ", bb.remaining(),
                            " bytes instead of the expected " + bigBlockSize.getBigBlockSize());
                toRead = bb.remaining();
             }
             
             bb.get(data, 0, toRead);
          }
          
          PropertyFactory.convertToProperties(data, properties);
       }
       return properties;
    }

    /**
     * Return the number of BigBlock's this instance uses
     *
     * @return count of BigBlock instances
     */
    public int countBlocks()
    {
       long rawSize = _properties.size() * (long)POIFSConstants.PROPERTY_SIZE;
       int blkSize = _bigBigBlockSize.getBigBlockSize();
       int numBlocks = (int)(rawSize / blkSize);
       if ((rawSize % blkSize) != 0) {
           numBlocks++;
       }
       return numBlocks;
    }
 
    /**
     * Prepare to be written
     */
    public void preWrite() {
        List<Property> pList = new ArrayList<Property>();
        // give each property its index
        int i=0;
        for (Property p : _properties) {
            // only handle non-null properties 
            if (p == null) continue;
            p.setIndex(i++);
            pList.add(p);
        }

        // prepare each property for writing
        for (Property p : pList) p.preWrite();
    }    
    
    /**
     * Writes the properties out into the given low-level stream
     */
    public void write(NPOIFSStream stream) throws IOException {
       OutputStream os = stream.getOutputStream();
       for(Property property : _properties) {
          if(property != null) {
             property.writeData(os);
          }
       }
       os.close();
       
       // Update the start position if needed
       if(getStartBlock() != stream.getStartBlock()) {
          setStartBlock(stream.getStartBlock());
       }
    }
}
