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

import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.IOUtils;
import org.apache.poi.POIXMLException;

import java.io.*;
import java.net.URI;

/**
 * Provides handy methods to work with OOXML packages
 */
public final class PackageHelper {

    public static OPCPackage open(InputStream is) throws IOException {
        try {
            return OPCPackage.open(is);
        } catch (InvalidFormatException e){
            throw new POIXMLException(e);
        }
    }

    /**
     * Clone the specified package.
     *
     * @param   pkg   the package to clone
     * @param   file  the destination file
     * @return  the cloned package
     */
    public static OPCPackage clone(OPCPackage pkg, File file) throws OpenXML4JException, IOException {

        String path = file.getAbsolutePath();

        OPCPackage dest = OPCPackage.create(path);
        PackageRelationshipCollection rels = pkg.getRelationships();
        for (PackageRelationship rel : rels) {
            PackagePart part = pkg.getPart(rel);
            PackagePart part_tgt;
            if (rel.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) {
                copyProperties(pkg.getPackageProperties(), dest.getPackageProperties());
                continue;
            }
            dest.addRelationship(part.getPartName(), rel.getTargetMode(), rel.getRelationshipType());
            part_tgt = dest.createPart(part.getPartName(), part.getContentType());

            OutputStream out = part_tgt.getOutputStream();
            IOUtils.copy(part.getInputStream(), out);
            out.close();

            if(part.hasRelationships()) {
                copy(pkg, part, dest, part_tgt);
            }
        }
        dest.close();

        //the temp file will be deleted when JVM terminates
        new File(path).deleteOnExit();
        return OPCPackage.open(path);
    }

    /**
     * Recursively copy package parts to the destination package
     */
    private static void copy(OPCPackage pkg, PackagePart part, OPCPackage tgt, PackagePart part_tgt) throws OpenXML4JException, IOException {
        PackageRelationshipCollection rels = part.getRelationships();
        if(rels != null) for (PackageRelationship rel : rels) {
            PackagePart p;
            if(rel.getTargetMode() == TargetMode.EXTERNAL){
                part_tgt.addExternalRelationship(rel.getTargetURI().toString(), rel.getRelationshipType(), rel.getId());
                //external relations don't have associated package parts
                continue;
            }
            URI uri = rel.getTargetURI();

            if(uri.getRawFragment() != null) {
                part_tgt.addRelationship(uri, rel.getTargetMode(), rel.getRelationshipType(), rel.getId());
                continue;
            }
            PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
            p = pkg.getPart(relName);
            part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId());




            PackagePart dest;
            if(!tgt.containPart(p.getPartName())){
                dest = tgt.createPart(p.getPartName(), p.getContentType());
                OutputStream out = dest.getOutputStream();
                IOUtils.copy(p.getInputStream(), out);
                out.close();
                copy(pkg, p, tgt, dest);
            }
        }
    }

    /**
     * Copy core package properties
     *
     * @param src source properties
     * @param tgt target properties
     */
    private static void copyProperties(PackageProperties src, PackageProperties tgt){
        tgt.setCategoryProperty(src.getCategoryProperty().getValue());
        tgt.setContentStatusProperty(src.getContentStatusProperty().getValue());
        tgt.setContentTypeProperty(src.getContentTypeProperty().getValue());
        tgt.setCreatorProperty(src.getCreatorProperty().getValue());
        tgt.setDescriptionProperty(src.getDescriptionProperty().getValue());
        tgt.setIdentifierProperty(src.getIdentifierProperty().getValue());
        tgt.setKeywordsProperty(src.getKeywordsProperty().getValue());
        tgt.setLanguageProperty(src.getLanguageProperty().getValue());
        tgt.setRevisionProperty(src.getRevisionProperty().getValue());
        tgt.setSubjectProperty(src.getSubjectProperty().getValue());
        tgt.setTitleProperty(src.getTitleProperty().getValue());
        tgt.setVersionProperty(src.getVersionProperty().getValue());
    }
}
