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

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.usermodel.XSSFRelation;

/**
 * Represents an entry of a OOXML package.
 *
 * <p>
 * Each POIXMLDocumentPart keeps a reference to the underlying a {@link org.apache.poi.openxml4j.opc.PackagePart}.
 * </p>
 */
public class POIXMLDocumentPart {
    private static final POILogger logger = POILogFactory.getLogger(POIXMLDocumentPart.class);

    private String coreDocumentRel = PackageRelationshipTypes.CORE_DOCUMENT;
    private PackagePart packagePart;
    private POIXMLDocumentPart parent;
    private Map<String,RelationPart> relations = new LinkedHashMap<String,RelationPart>();

    /**
     * The RelationPart is a cached relationship between the document, which contains the RelationPart,
     * and one of its referenced child document parts.
     * The child document parts may only belong to one parent, but it's often referenced by other
     * parents too, having varying {@link PackageRelationship#getId() relationship ids} pointing to it.
     */
    public static class RelationPart {
        private final PackageRelationship relationship;
        private final POIXMLDocumentPart documentPart;
        
        RelationPart(PackageRelationship relationship, POIXMLDocumentPart documentPart) {
            this.relationship = relationship;
            this.documentPart = documentPart;
        }
        
        /**
         * @return the cached relationship, which uniquely identifies this child document part within the parent 
         */
        public PackageRelationship getRelationship() {
            return relationship;
        }
        
        /**
         * @param <T> the cast of the caller to a document sub class
         * 
         * @return the child document part
         */
        @SuppressWarnings("unchecked")
        public <T extends POIXMLDocumentPart> T getDocumentPart() {
            return (T)documentPart;
        }
    }

    /**
     * Counter that provides the amount of incoming relations from other parts
     * to this part.
     */
    private int relationCounter = 0;

    int incrementRelationCounter() {
        relationCounter++;
        return relationCounter;
    }

    int decrementRelationCounter() {
        relationCounter--;
        return relationCounter;
    }

    int getRelationCounter() {
        return relationCounter;
    }

    /**
     * Construct POIXMLDocumentPart representing a "core document" package part.
     * 
     * @param pkg the OPCPackage containing this document
     */
    public POIXMLDocumentPart(OPCPackage pkg) {
        this(pkg, PackageRelationshipTypes.CORE_DOCUMENT);
    }

    /**
     * Construct POIXMLDocumentPart representing a custom "core document" package part.
     * 
     * @param pkg the OPCPackage containing this document
     * @param coreDocumentRel the relation type of this document 
     */
    public POIXMLDocumentPart(OPCPackage pkg, String coreDocumentRel) {
        this(getPartFromOPCPackage(pkg, coreDocumentRel));
        this.coreDocumentRel = coreDocumentRel;
    }
    
    /**
     * Creates new POIXMLDocumentPart   - called by client code to create new parts from scratch.
     *
     * @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)
     */
    public POIXMLDocumentPart() {
    }

    /**
     * Creates an POIXMLDocumentPart representing the given package part and relationship.
     * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file.
     *
     * @param part - The package part that holds xml data representing this sheet.
     * @see #read(POIXMLFactory, java.util.Map)
     *
     * @since POI 3.14-Beta1
     */
    public POIXMLDocumentPart(PackagePart part) {
        this(null, part);
    }

    /**
     * Creates an POIXMLDocumentPart representing the given package part, relationship and parent
     * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file.
     *
     * @param parent - Parent part
     * @param part - The package part that holds xml data representing this sheet.
     * @see #read(POIXMLFactory, java.util.Map)
     *
     * @since POI 3.14-Beta1
     */
    public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part) {
        this.packagePart = part;
        this.parent = parent;
    }

    /**
     * When you open something like a theme, call this to
     *  re-base the XML Document onto the core child of the
     *  current core document
     * 
     * @param pkg the package to be rebased
     * 
     * @throws InvalidFormatException if there was an error in the core document relation 
     * @throws IllegalStateException if there are more than one core document relations
     */
    protected final void rebase(OPCPackage pkg) throws InvalidFormatException {
        PackageRelationshipCollection cores =
            packagePart.getRelationshipsByType(coreDocumentRel);
        if(cores.size() != 1) {
            throw new IllegalStateException(
                "Tried to rebase using " + coreDocumentRel +
                " but found " + cores.size() + " parts of the right type"
            );
        }
        packagePart = packagePart.getRelatedPart(cores.getRelationship(0));
    }

    /**
     * Provides access to the underlying PackagePart
     *
     * @return the underlying PackagePart
     */
    public final PackagePart getPackagePart(){
        return packagePart;
    }

    /**
     * Returns the list of child relations for this POIXMLDocumentPart
     *
     * @return child relations
     */
    public final List<POIXMLDocumentPart> getRelations(){
        List<POIXMLDocumentPart> l = new ArrayList<POIXMLDocumentPart>();
        for (RelationPart rp : relations.values()) {
            l.add(rp.getDocumentPart());
        }
        return Collections.unmodifiableList(l);
    }

    /**
     * Returns the list of child relations for this POIXMLDocumentPart
     *
     * @return child relations
     */
    public final List<RelationPart> getRelationParts() {
        List<RelationPart> l = new ArrayList<RelationPart>(relations.values());
        return Collections.unmodifiableList(l);
    }

    /**
     * Returns the target {@link POIXMLDocumentPart}, where a
     * {@link PackageRelationship} is set from the {@link PackagePart} of this
     * {@link POIXMLDocumentPart} to the {@link PackagePart} of the target
     * {@link POIXMLDocumentPart} with a {@link PackageRelationship#getId()}
     * matching the given parameter value.
     *
     * @param id
     *            The relation id to look for
     * @return the target part of the relation, or null, if none exists
     */
    public final POIXMLDocumentPart getRelationById(String id) {
        RelationPart rp = relations.get(id);
        return (rp == null) ? null : rp.getDocumentPart();
    }

    /**
     * Returns the {@link PackageRelationship#getId()} of the
     * {@link PackageRelationship}, that sources from the {@link PackagePart} of
     * this {@link POIXMLDocumentPart} to the {@link PackagePart} of the given
     * parameter value.
     *
     * @param part
     *            The {@link POIXMLDocumentPart} for which the according
     *            relation-id shall be found.
     * @return The value of the {@link PackageRelationship#getId()} or null, if
     *         parts are not related.
     */
    public final String getRelationId(POIXMLDocumentPart part) {
        for (RelationPart rp : relations.values()) {
            if (rp.getDocumentPart() == part) {
                return rp.getRelationship().getId();
            }
        }
        return null;
    }

    /**
     * Add a new child POIXMLDocumentPart
     *
     * @param relId the preferred relation id, when null the next free relation id will be used
     * @param relationshipType the package relationship type
     * @param part the child to add
     * 
     * @return the new RelationPart
     *
     * @since 3.14-Beta1
     */
    public final RelationPart addRelation(String relId, POIXMLRelation relationshipType, POIXMLDocumentPart part) {
        PackageRelationship pr = this.packagePart.findExistingRelation(part.getPackagePart());
        if (pr == null) {
            PackagePartName ppn = part.getPackagePart().getPartName();
            String relType = relationshipType.getRelation();
            pr = packagePart.addRelationship(ppn, TargetMode.INTERNAL, relType, relId);
        }
        addRelation(pr, part);
        return new RelationPart(pr, part);
    }

    /**
     * Add a new child POIXMLDocumentPart
     *
     * @param pr the relationship of the child
     * @param part the child to add
     */
    private void addRelation(PackageRelationship pr, POIXMLDocumentPart part) {
        relations.put(pr.getId(), new RelationPart(pr,part));
        part.incrementRelationCounter();

    }

    /**
     * Remove the relation to the specified part in this package and remove the
     * part, if it is no longer needed.
     * 
     * @param part the part which relation is to be removed from this document
     */
    protected final void removeRelation(POIXMLDocumentPart part){
        removeRelation(part,true);
    }

    /**
     * Remove the relation to the specified part in this package and remove the
     * part, if it is no longer needed and flag is set to true.
     *
     * @param part
     *            The related part, to which the relation shall be removed.
     * @param removeUnusedParts
     *            true, if the part shall be removed from the package if not
     *            needed any longer.
     * @return true, if the relation was removed
     */
    protected final boolean removeRelation(POIXMLDocumentPart part, boolean removeUnusedParts){
        String id = getRelationId(part);
        if (id == null) {
            // part is not related with this POIXMLDocumentPart
            return false;
        }
        /* decrement usage counter */
        part.decrementRelationCounter();
        /* remove packagepart relationship */
        getPackagePart().removeRelationship(id);
        /* remove POIXMLDocument from relations */
        relations.remove(id);

        if (removeUnusedParts) {
            /* if last relation to target part was removed, delete according target part */
            if (part.getRelationCounter() == 0) {
                try {
                    part.onDocumentRemove();
                } catch (IOException e) {
                    throw new POIXMLException(e);
                }
                getPackagePart().getPackage().removePart(part.getPackagePart());
            }
        }
        return true;
    }

    /**
     * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent.
     *
     * @return the parent POIXMLDocumentPart or <code>null</code> for the root element.
     */
    public final POIXMLDocumentPart getParent(){
        return parent;
    }

    @Override
    public String toString(){
        return packagePart == null ? "" : packagePart.toString();
    }

    /**
     * Save the content in the underlying package part.
     * Default implementation is empty meaning that the package part is left unmodified.
     *
     * Sub-classes should override and add logic to marshal the "model" into Ooxml4J.
     *
     * For example, the code saving a generic XML entry may look as follows:
     * <pre>
     * protected void commit() throws IOException {
     *   PackagePart part = getPackagePart();
     *   OutputStream out = part.getOutputStream();
     *   XmlObject bean = getXmlBean(); //the "model" which holds changes in memory
     *   bean.save(out, DEFAULT_XML_OPTIONS);
     *   out.close();
     * }
     * </pre>
     * 
     * @throws IOException a subclass may throw an IOException if the changes can't be committed
     */
    protected void commit() throws IOException {

    }

    /**
     * Save changes in the underlying OOXML package.
     * Recursively fires {@link #commit()} for each package part
     *
     * @param alreadySaved    context set containing already visited nodes
     * 
     * @throws IOException a related part may throw an IOException if the changes can't be saved
     */
    protected final void onSave(Set<PackagePart> alreadySaved) throws IOException{
        // this usually clears out previous content in the part...
        prepareForCommit();

        commit();
        alreadySaved.add(this.getPackagePart());
        for(RelationPart rp : relations.values()){
            POIXMLDocumentPart p = rp.getDocumentPart();
            if (!alreadySaved.contains(p.getPackagePart())) {
                p.onSave(alreadySaved);
            }
        }
    }

    /**
     * Ensure that a memory based package part does not have lingering data from previous
     * commit() calls.
     *
     * Note: This is overwritten for some objects, as *PictureData seem to store the actual content
     * in the part directly without keeping a copy like all others therefore we need to handle them differently.
     */
    protected void prepareForCommit() {
        PackagePart part = this.getPackagePart();
        if(part != null) {
            part.clear();
        }
    }

    /**
     * Create a new child POIXMLDocumentPart
     *
     * @param descriptor the part descriptor
     * @param factory the factory that will create an instance of the requested relation
     * @return the created child POIXMLDocumentPart
     * @throws PartAlreadyExistsException
     *             If rule M1.12 is not verified : Packages shall not contain
     *             equivalent part names and package implementers shall neither
     *             create nor recognize packages with equivalent part names.
     */
    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
        return createRelationship(descriptor, factory, -1, false).getDocumentPart();
    }

    /**
     * Create a new child POIXMLDocumentPart
     *
     * @param descriptor the part descriptor
     * @param factory the factory that will create an instance of the requested relation
     * @param idx part number
     * @return the created child POIXMLDocumentPart
     * @throws PartAlreadyExistsException
     *             If rule M1.12 is not verified : Packages shall not contain
     *             equivalent part names and package implementers shall neither
     *             create nor recognize packages with equivalent part names.
     */
    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
        return createRelationship(descriptor, factory, idx, false).getDocumentPart();
    }
    
    /**
     * Identifies the next available part number for a part of the given type,
     *  if possible, otherwise -1 if none are available.
     * The found (valid) index can then be safely given to
     *  {@link #createRelationship(POIXMLRelation, POIXMLFactory, int)} or
     *  {@link #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)}
     *  without naming clashes.
     * If parts with other types are already claiming a name for this relationship
     *  type (eg a {@link XSSFRelation#CHART} using the drawing part namespace 
     *  normally used by {@link XSSFRelation#DRAWINGS}), those will be considered
     *  when finding the next spare number.
     *
     * @param descriptor The relationship type to find the part number for
     * @param minIdx The minimum free index to assign, use -1 for any
     * @return The next free part number, or -1 if none available
     */
    protected final int getNextPartNumber(POIXMLRelation descriptor, int minIdx) {
        OPCPackage pkg = packagePart.getPackage();
        
        try {
            String name = descriptor.getDefaultFileName();
            if (name.equals(descriptor.getFileName(9999))) {
                // Non-index based, check if default is free
                PackagePartName ppName = PackagingURIHelper.createPartName(name);
                if (pkg.containPart(ppName)) {
                    // Default name already taken, not index based, nothing free
                    return -1;
                } else {
                    // Default name free
                    return 0;
                }
            }
            
            // Default to searching from 1, unless they asked for 0+
            int idx = (minIdx < 0) ? 1 : minIdx;
            int maxIdx = minIdx + pkg.getParts().size();
            while (idx <= maxIdx) {
                name = descriptor.getFileName(idx);
                PackagePartName ppName = PackagingURIHelper.createPartName(name);
                if (!pkg.containPart(ppName)) {
                    return idx;
                }
                idx++;
            }
        } catch (InvalidFormatException e) {
            // Give a general wrapped exception for the problem
            throw new POIXMLException(e);
        }
        return -1;
    }

    /**
     * Create a new child POIXMLDocumentPart
     *
     * @param descriptor the part descriptor
     * @param factory the factory that will create an instance of the requested relation
     * @param idx part number
     * @param noRelation if true, then no relationship is added.
     * @return the created child POIXMLDocumentPart
     * @throws PartAlreadyExistsException
     *             If rule M1.12 is not verified : Packages shall not contain
     *             equivalent part names and package implementers shall neither
     *             create nor recognize packages with equivalent part names.
     */
    protected final RelationPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){
        try {
            PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
            PackageRelationship rel = null;
            PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
            if(!noRelation) {
                /* only add to relations, if according relationship is being created. */
                rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
            }
            POIXMLDocumentPart doc = factory.newDocumentPart(descriptor);
            doc.packagePart = part;
            doc.parent = this;
            if (!noRelation) {
                /* only add to relations, if according relationship is being created. */
                addRelation(rel,doc);
            }

            return new RelationPart(rel,doc);
        } catch (PartAlreadyExistsException pae) {
           // Return the specific exception so the user knows
           //  that the name is already taken
           throw pae;
        } catch (Exception e){
           // Give a general wrapped exception for the problem
           throw new POIXMLException(e);
        }
    }

    /**
     * Iterate through the underlying PackagePart and create child POIXMLFactory instances
     * using the specified factory
     *
     * @param factory   the factory object that creates POIXMLFactory instances
     * @param context   context map containing already visited noted keyed by targetURI
     * 
     * @throws OpenXML4JException thrown when a related part can't be read
     */
    protected void read(POIXMLFactory factory, Map<PackagePart, POIXMLDocumentPart> context) throws OpenXML4JException {
        PackagePart pp = getPackagePart();
        // add mapping a second time, in case of initial caller hasn't done so
        POIXMLDocumentPart otherChild = context.put(pp, this);
        if (otherChild != null && otherChild != this) {
            throw new POIXMLException("Unique PackagePart-POIXMLDocumentPart relation broken!");
        }

        if (!pp.hasRelationships()) return;

        PackageRelationshipCollection rels = packagePart.getRelationships();
        List<POIXMLDocumentPart> readLater = new ArrayList<POIXMLDocumentPart>();

        // scan breadth-first, so parent-relations are hopefully the shallowest element
        for (PackageRelationship rel : rels) {
            if(rel.getTargetMode() == TargetMode.INTERNAL){
                URI uri = rel.getTargetURI();

                // check for internal references (e.g. '#Sheet1!A1')
                PackagePartName relName;
                if(uri.getRawFragment() != null) {
                    relName = PackagingURIHelper.createPartName(uri.getPath());
                } else {
                    relName = PackagingURIHelper.createPartName(uri);
                }

                final PackagePart p = packagePart.getPackage().getPart(relName);
                if (p == null) {
                    logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI());
                    continue;
                }

                POIXMLDocumentPart childPart = context.get(p);
                if (childPart == null) {
                    childPart = factory.createDocumentPart(this, p);
                    childPart.parent = this;
                    // already add child to context, so other children can reference it
                    context.put(p, childPart);
                    readLater.add(childPart);
                }

                addRelation(rel,childPart);
            }
        }

        for (POIXMLDocumentPart childPart : readLater) {
            childPart.read(factory, context);
        }
    }

    /**
     * Get the PackagePart that is the target of a relationship from this Part.
     *
     * @param rel The relationship
     * @return The target part
     * @throws InvalidFormatException thrown if the related part has is erroneous
     */
    protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException {
        return getPackagePart().getRelatedPart(rel);
    }


    /**
     * Fired when a new package part is created
     * 
     * @throws IOException a subclass may throw an IOException on document creation
     */
    protected void onDocumentCreate() throws IOException {

    }

    /**
     * Fired when a package part is read
     * 
     * @throws IOException a subclass may throw an IOException when a document is read
     */
    protected void onDocumentRead() throws IOException {

    }

    /**
     * Fired when a package part is about to be removed from the package
     * 
     * @throws IOException a subclass may throw an IOException when a document is removed
     */
    protected void onDocumentRemove() throws IOException {

    }

    /**
     * Internal method, do not use!
     * <p>
     * This method only exists to allow access to protected {@link POIXMLDocumentPart#onDocumentRead()}
     * from {@link org.apache.poi.xwpf.usermodel.XWPFDocument} without reflection. It should be removed.
     * 
     * @param part the part which is to be read
     * 
     * @throws IOException if the part can't be read
     */
    @Internal @Deprecated
    public static void _invokeOnDocumentRead(POIXMLDocumentPart part) throws IOException {
        part.onDocumentRead();
    }

    /**
     * Retrieves the core document part
     * 
     * @since POI 3.14-Beta1
     */
    private static PackagePart getPartFromOPCPackage(OPCPackage pkg, String coreDocumentRel) {
        PackageRelationship coreRel = pkg.getRelationshipsByType(coreDocumentRel).getRelationship(0);

        if (coreRel != null) {
            PackagePart pp = pkg.getPart(coreRel);
            if (pp == null) {
                throw new POIXMLException("OOXML file structure broken/invalid - core document '"+coreRel.getTargetURI()+"' not found.");
            }
            return pp;
        }
        
        coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0);
        if (coreRel != null) {
            throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699");
        }

        throw new POIXMLException("OOXML file structure broken/invalid - no core document found!");
    }
}
