/* ====================================================================
   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.openxml4j.opc.internal;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.ZipPackage;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.openxml4j.util.ZipSecureFile.ThresholdInputStream;
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.storage.HeaderBlockConstants;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;

public final class ZipHelper {
    /**
     * Forward slash use to convert part name between OPC and zip item naming
     * conventions.
     */
    private final static String FORWARD_SLASH = "/";

    /**
     * Buffer to read data from file. Use big buffer to improve performaces. the
     * InputStream class is reading only 8192 bytes per read call (default value
     * set by sun)
     */
    public static final int READ_WRITE_FILE_BUFFER_SIZE = 8192;

    /**
     * Prevent this class to be instancied.
     */
    private ZipHelper() {
        // Do nothing
    }

    /**
     * Retrieve the zip entry of the core properties part.
     *
     * @throws OpenXML4JException
     *             Throws if internal error occurs.
     */
    public static ZipEntry getCorePropertiesZipEntry(ZipPackage pkg) {
        PackageRelationship corePropsRel = pkg.getRelationshipsByType(
                PackageRelationshipTypes.CORE_PROPERTIES).getRelationship(0);

        if (corePropsRel == null)
            return null;

        return new ZipEntry(corePropsRel.getTargetURI().getPath());
    }

    /**
     * Retrieve the Zip entry of the content types part.
     */
    public static ZipEntry getContentTypeZipEntry(ZipPackage pkg) {
        Enumeration<? extends ZipEntry> entries = pkg.getZipArchive().getEntries();

        // Enumerate through the Zip entries until we find the one named
        // '[Content_Types].xml'.
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            if (entry.getName().equals(
                    ContentTypeManager.CONTENT_TYPES_PART_NAME))
                return entry;
        }
        return null;
    }

    /**
     * Convert a zip name into an OPC name by adding a leading forward slash to
     * the specified item name.
     *
     * @param zipItemName
     *            Zip item name to convert.
     * @return An OPC compliant name.
     */
    public static String getOPCNameFromZipItemName(String zipItemName) {
        if (zipItemName == null)
            throw new IllegalArgumentException("zipItemName");
        if (zipItemName.startsWith(FORWARD_SLASH)) {
            return zipItemName;
        }
        return FORWARD_SLASH + zipItemName;
    }

    /**
     * Convert an OPC item name into a zip item name by removing any leading
     * forward slash if it exist.
     *
     * @param opcItemName
     *            The OPC item name to convert.
     * @return A zip item name without any leading slashes.
     */
    public static String getZipItemNameFromOPCName(String opcItemName) {
        if (opcItemName == null)
            throw new IllegalArgumentException("opcItemName");

        String retVal = opcItemName;
        while (retVal.startsWith(FORWARD_SLASH))
            retVal = retVal.substring(1);
        return retVal;
    }

    /**
     * Convert an OPC item name into a zip URI by removing any leading forward
     * slash if it exist.
     *
     * @param opcItemName
     *            The OPC item name to convert.
     * @return A zip URI without any leading slashes.
     */
    public static URI getZipURIFromOPCName(String opcItemName) {
        if (opcItemName == null)
            throw new IllegalArgumentException("opcItemName");

        String retVal = opcItemName;
        while (retVal.startsWith(FORWARD_SLASH))
            retVal = retVal.substring(1);
        try {
            return new URI(retVal);
        } catch (URISyntaxException e) {
            return null;
        }
    }
    
    /**
     * Verifies that the given stream starts with a Zip structure.
     * 
     * Warning - this will consume the first few bytes of the stream,
     *  you should push-back or reset the stream after use!
     */
    public static void verifyZipHeader(InputStream stream) 
            throws NotOfficeXmlFileException, IOException {
        // Grab the first 8 bytes
        byte[] data = new byte[8];
        IOUtils.readFully(stream, data);
        
        // OLE2?
        long signature = LittleEndian.getLong(data);
        if (signature == HeaderBlockConstants._signature) {
            throw new OLE2NotOfficeXmlFileException(
                "The supplied data appears to be in the OLE2 Format. " +
                "You are calling the part of POI that deals with OOXML "+
                "(Office Open XML) Documents. You need to call a different " +
                "part of POI to process this data (eg HSSF instead of XSSF)");
        }
        
        // Raw XML?
        byte[] RAW_XML_FILE_HEADER = POIFSConstants.RAW_XML_FILE_HEADER;
        if (data[0] == RAW_XML_FILE_HEADER[0] &&
            data[1] == RAW_XML_FILE_HEADER[1] &&
            data[2] == RAW_XML_FILE_HEADER[2] &&
            data[3] == RAW_XML_FILE_HEADER[3] &&
            data[4] == RAW_XML_FILE_HEADER[4]) {
            throw new NotOfficeXmlFileException(
                "The supplied data appears to be a raw XML file. " +
                "Formats such as Office 2003 XML are not supported");
        }

        // Don't check for a Zip header, as to maintain backwards
        //  compatibility we need to let them seek over junk at the
        //  start before beginning processing.
        
        // Put things back
        if (stream instanceof PushbackInputStream) {
            ((PushbackInputStream)stream).unread(data);
        } else if (stream.markSupported()) {
            stream.reset();
        } else if (stream instanceof FileInputStream) {
            // File open check, about to be closed, nothing to do
        } else {
            // Oh dear... I hope you know what you're doing!
        }
    }
    
    private static InputStream prepareToCheckHeader(InputStream stream) {
        if (stream instanceof PushbackInputStream) {
            return stream;
        }
        if (stream.markSupported()) {
            stream.mark(8);
            return stream;
        }
        return new PushbackInputStream(stream, 8);
    }

    /**
     * Opens the specified stream as a secure zip
     *
     * @param stream
     *            The stream to open.
     * @return The zip stream freshly open.
     */
    @SuppressWarnings("resource")
    public static ThresholdInputStream openZipStream(InputStream stream) throws IOException {
        // Peek at the first few bytes to sanity check
        InputStream checkedStream = prepareToCheckHeader(stream);
        verifyZipHeader(checkedStream);
        
        // Open as a proper zip stream
        InputStream zis = new ZipInputStream(checkedStream);
        return ZipSecureFile.addThreshold(zis);
    }

    /**
     * Opens the specified file as a secure zip, or returns null if no 
     *  such file exists
     *
     * @param file
     *            The file to open.
     * @return The zip archive freshly open.
     */
    public static ZipFile openZipFile(File file) throws IOException {
        if (!file.exists()) {
            return null;
        }
        
        // Peek at the first few bytes to sanity check
        FileInputStream input = new FileInputStream(file);
        try {
            verifyZipHeader(input);
        } finally {
            input.close();
        }

        // Open as a proper zip file
        return new ZipSecureFile(file);
    }

    /**
     * Retrieve and open as a secure zip file with the specified path.
     *
     * @param path
     *            The file path.
     * @return The zip archive freshly open.
     */
    public static ZipFile openZipFile(String path) throws IOException {
        return openZipFile(new File(path));
    }
}
