/*
 * 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.sling.servlets.post.impl.operations;

import java.util.List;

import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.VersioningConfiguration;

/**
 * The <code>CopyOperation</code> class implements the
 * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_COPY copy}
 * operation for the Sling default POST servlet.
 */
public class CopyOperation extends AbstractCopyMoveOperation {

    @Override
    protected String getOperationName() {
        return "copy";
    }

    @Override
    protected Resource execute(List<Modification> changes,
            Resource source,
            String destParent, String destName,
            VersioningConfiguration versioningConfiguration) throws RepositoryException {
        // ensure we have an item underlying the request's resource
        Item item = source.adaptTo(Item.class);
        if (item == null) {
            return null;
        }

        Item destItem = copy(item, (Node) item.getSession().getItem(destParent), destName);

        String dest = destParent + "/" + destName;
        changes.add(Modification.onCopied(source.getPath(), dest));
        log.debug("copy {} to {}", source, dest);
        return source.getResourceResolver().getResource(destItem.getPath());
    }

    /**
     * Copy the <code>src</code> item into the <code>dstParent</code> node.
     * The name of the newly created item is set to <code>name</code>.
     *
     * @param src The item to copy to the new location
     * @param dstParent The node into which the <code>src</code> node is to be
     *            copied
     * @param name The name of the newly created item. If this is
     *            <code>null</code> the new item gets the same name as the
     *            <code>src</code> item.
     * @throws RepositoryException May be thrown in case of any problem copying
     *             the content.
     * @see #copy(Node, Node, String)
     * @see #copy(Property, Node, String)
     */
    static Item copy(Item src, Node dstParent, String name)
            throws RepositoryException {
        if (src.isNode()) {
            return copy((Node) src, dstParent, name);
        }
        return copy((Property) src, dstParent, name);
    }

    /**
     * Copy the <code>src</code> node into the <code>dstParent</code> node.
     * The name of the newly created node is set to <code>name</code>.
     * <p>
     * This method does a recursive (deep) copy of the subtree rooted at the
     * source node to the destination. Any protected child nodes and and
     * properties are not copied.
     *
     * @param src The node to copy to the new location
     * @param dstParent The node into which the <code>src</code> node is to be
     *            copied
     * @param name The name of the newly created node. If this is
     *            <code>null</code> the new node gets the same name as the
     *            <code>src</code> node.
     * @throws RepositoryException May be thrown in case of any problem copying
     *             the content.
     */
    static Item copy(Node src, Node dstParent, String name)
            throws RepositoryException {

        if(isAncestorOrSameNode(src, dstParent)) {
            throw new RepositoryException(
                    "Cannot copy ancestor " + src.getPath() + " to descendant " + dstParent.getPath());
        }

        // ensure destination name
        if (name == null) {
            name = src.getName();
        }

        // ensure new node creation
        if (dstParent.hasNode(name)) {
            dstParent.getNode(name).remove();
        }

        // create new node
        Node dst = dstParent.addNode(name, src.getPrimaryNodeType().getName());
        for (NodeType mix : src.getMixinNodeTypes()) {
            dst.addMixin(mix.getName());
        }

        // copy the properties
        for (PropertyIterator iter = src.getProperties(); iter.hasNext();) {
            copy(iter.nextProperty(), dst, null);
        }

        // copy the child nodes
        for (NodeIterator iter = src.getNodes(); iter.hasNext();) {
            Node n = iter.nextNode();
            if (!n.getDefinition().isProtected()) {
                copy(n, dst, null);
            }
        }
        return dst;
    }

    /** @return true if src is an ancestor node of dest, or if
     *  both are the same node */
    static boolean isAncestorOrSameNode(Node src, Node dest) throws RepositoryException {
        if(src.getPath().equals("/")) {
            return true;
        } else if(src.getPath().equals(dest.getPath())) {
            return true;
        } else if(dest.getPath().startsWith(src.getPath() + "/")) {
            return true;
        }
        return false;
    }

    /**
     * Copy the <code>src</code> property into the <code>dstParent</code>
     * node. The name of the newly created property is set to <code>name</code>.
     * <p>
     * If the source property is protected, this method does nothing.
     *
     * @param src The property to copy to the new location
     * @param dstParent The node into which the <code>src</code> property is
     *            to be copied
     * @param name The name of the newly created property. If this is
     *            <code>null</code> the new property gets the same name as the
     *            <code>src</code> property.
     * @throws RepositoryException May be thrown in case of any problem copying
     *             the content.
     */
    static Item copy(Property src, Node dstParent, String name)
            throws RepositoryException {
        if (!src.getDefinition().isProtected()) {
            if (name == null) {
                name = src.getName();
            }

            // ensure new property creation
            if (dstParent.hasProperty(name)) {
                dstParent.getProperty(name).remove();
            }

            if (src.getDefinition().isMultiple()) {
                return dstParent.setProperty(name, src.getValues());
            }
            return dstParent.setProperty(name, src.getValue());
        }
        return null;
    }

}
