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

import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import javax.servlet.ServletContext;

import org.apache.sling.api.SlingException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.SlingPostConstants;
import org.apache.sling.servlets.post.VersioningConfiguration;
import org.apache.sling.servlets.post.impl.helper.DateParser;
import org.apache.sling.servlets.post.impl.helper.RequestProperty;
import org.apache.sling.servlets.post.impl.helper.SlingFileUploadHandler;
import org.apache.sling.servlets.post.impl.helper.SlingPropertyValueHandler;

/**
 * The <code>ModifyOperation</code> class implements the default operation
 * called by the Sling default POST servlet if no operation is requested by the
 * client. This operation is able to create and/or modify content.
 */
public class ModifyOperation extends AbstractCreateOperation {

    private DateParser dateParser;

    /**
     * handler that deals with file upload
     */
    private final SlingFileUploadHandler uploadHandler;

    public ModifyOperation() {
        this.dateParser = new DateParser();
        this.uploadHandler = new SlingFileUploadHandler();
    }

    public void setServletContext(final ServletContext servletContext) {
        this.uploadHandler.setServletContext(servletContext);
    }

    public void setDateParser(final DateParser dateParser) {
        this.dateParser = dateParser;
    }

    @Override
    protected void doRun(final SlingHttpServletRequest request,
                    final PostResponse response,
                    final List<Modification> changes)
    throws PersistenceException {

        try {
            final Map<String, RequestProperty> reqProperties = collectContent(request, response);

            final VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);

            // do not change order unless you have a very good reason.

            // ensure root of new content
            processCreate(request.getResourceResolver(), reqProperties, response, changes, versioningConfiguration);

            // write content from existing content (@Move/CopyFrom parameters)
            processMoves(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);
            processCopies(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);

            // cleanup any old content (@Delete parameters)
            processDeletes(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);

            // write content from form
            writeContent(request.getResourceResolver(), reqProperties, changes, versioningConfiguration);

            // order content
            final Resource newResource = request.getResourceResolver().getResource(response.getPath());
            this.jcrSsupport.orderNode(request, newResource, changes);
        } catch ( final RepositoryException pe) {
            throw new PersistenceException(pe.getMessage(), pe);
        }
    }

    @Override
    protected String getResourcePath(SlingHttpServletRequest request) {

        // calculate the paths
        StringBuilder rootPathBuf = new StringBuilder();
        String suffix;
        Resource currentResource = request.getResource();
        if (ResourceUtil.isSyntheticResource(currentResource)) {

            // no resource, treat the missing resource path as suffix
            suffix = currentResource.getPath();

        } else {

            // resource for part of the path, use request suffix
            suffix = request.getRequestPathInfo().getSuffix();

            if (suffix != null) {
                // cut off any selectors/extension from the suffix
                int dotPos = suffix.indexOf('.');
                if (dotPos > 0) {
                    suffix = suffix.substring(0, dotPos);
                }
            }

            // and preset the path buffer with the resource path
            rootPathBuf.append(currentResource.getPath());

        }

        // check for extensions or create suffix in the suffix
        boolean doGenerateName = false;
        if (suffix != null) {

            // check whether it is a create request (trailing /)
            if (suffix.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX)) {
                suffix = suffix.substring(0, suffix.length()
                    - SlingPostConstants.DEFAULT_CREATE_SUFFIX.length());
                doGenerateName = true;

                // or with the star suffix /*
            } else if (suffix.endsWith(SlingPostConstants.STAR_CREATE_SUFFIX)) {
                suffix = suffix.substring(0, suffix.length()
                    - SlingPostConstants.STAR_CREATE_SUFFIX.length());
                doGenerateName = true;
            }

            // append the remains of the suffix to the path buffer
            rootPathBuf.append(suffix);

        }

        String path = rootPathBuf.toString();

        if (doGenerateName) {
            try {
                path = generateName(request, path);
            } catch (PersistenceException re) {
                throw new SlingException("Failed to generate name", re);
            }
        }

        return path;
    }

    /**
     * Moves all repository content listed as repository move source in the
     * request properties to the locations indicated by the resource properties.
     * @param checkedOutNodes
     */
    private void processMoves(final ResourceResolver resolver,
            Map<String, RequestProperty> reqProperties, List<Modification> changes,
            VersioningConfiguration versioningConfiguration)
            throws RepositoryException, PersistenceException {

        for (RequestProperty property : reqProperties.values()) {
            if (property.hasRepositoryMoveSource()) {
                processMovesCopiesInternal(property, true, resolver,
                    reqProperties, changes, versioningConfiguration);
            }
        }
    }

    /**
     * Copies all repository content listed as repository copy source in the
     * request properties to the locations indicated by the resource properties.
     * @param checkedOutNodes
     */
    private void processCopies(final ResourceResolver resolver,
            Map<String, RequestProperty> reqProperties, List<Modification> changes,
            VersioningConfiguration versioningConfiguration)
            throws RepositoryException, PersistenceException {

        for (RequestProperty property : reqProperties.values()) {
            if (property.hasRepositoryCopySource()) {
                processMovesCopiesInternal(property, false, resolver,
                    reqProperties, changes, versioningConfiguration);
            }
        }
    }

    /**
     * Internal implementation of the
     * {@link #processCopies(Session, Map, HtmlResponse)} and
     * {@link #processMoves(Session, Map, HtmlResponse)} methods taking into
     * account whether the source is actually a property or a node.
     * <p>
     * Any intermediary nodes to the destination as indicated by the
     * <code>property</code> path are created using the
     * <code>reqProperties</code> as indications for required node types.
     *
     * @param property The {@link RequestProperty} identifying the source
     *            content of the operation.
     * @param isMove <code>true</code> if the source item is to be moved.
     *            Otherwise the source item is just copied.
     * @param session The repository session to use to access the content
     * @param reqProperties All accepted request properties. This is used to
     *            create intermediary nodes along the property path.
     * @param response The <code>HtmlResponse</code> into which successfull
     *            copies and moves as well as intermediary node creations are
     *            recorded.
     * @throws RepositoryException May be thrown if an error occurrs.
     */
    private void processMovesCopiesInternal(
                    RequestProperty property,
            boolean isMove, final ResourceResolver resolver,
            Map<String, RequestProperty> reqProperties, List<Modification> changes,
            VersioningConfiguration versioningConfiguration)
            throws RepositoryException, PersistenceException {

        final Session session = resolver.adaptTo(Session.class);
        String propPath = property.getPath();
        String source = property.getRepositorySource();

        // only continue here, if the source really exists
        if (session.itemExists(source)) {

            // if the destination item already exists, remove it
            // first, otherwise ensure the parent location
            if (session.itemExists(propPath)) {
                Node parent = session.getItem(propPath).getParent();
                this.jcrSsupport.checkoutIfNecessary(resolver.getResource(parent.getPath()), changes, versioningConfiguration);

                session.getItem(propPath).remove();
                changes.add(Modification.onDeleted(propPath));
            } else {
                Resource parent = deepGetOrCreateResource(resolver, property.getParentPath(),
                    reqProperties, changes, versioningConfiguration);
                this.jcrSsupport.checkoutIfNecessary(parent, changes, versioningConfiguration);
            }

            // move through the session and record operation
            Item sourceItem = session.getItem(source);
            if (sourceItem.isNode()) {

                // node move/copy through session
                if (isMove) {
                    this.jcrSsupport.checkoutIfNecessary(resolver.getResource(sourceItem.getParent().getPath()), changes, versioningConfiguration);
                    session.move(source, propPath);
                } else {
                    Node sourceNode = (Node) sourceItem;
                    Node destParent = (Node) session.getItem(property.getParentPath());
                    this.jcrSsupport.checkoutIfNecessary(resolver.getResource(destParent.getPath()), changes, versioningConfiguration);
                    CopyOperation.copy(sourceNode, destParent,
                        property.getName());
                }

            } else {

                // property move manually
                Property sourceProperty = (Property) sourceItem;

                // create destination property
                Node destParent = (Node) session.getItem(property.getParentPath());
                this.jcrSsupport.checkoutIfNecessary(resolver.getResource(destParent.getPath()), changes, versioningConfiguration);
                CopyOperation.copy(sourceProperty, destParent, null);

                // remove source property (if not just copying)
                if (isMove) {
                    this.jcrSsupport.checkoutIfNecessary(resolver.getResource(sourceProperty.getParent().getPath()), changes, versioningConfiguration);
                    sourceProperty.remove();
                }
            }

            // make sure the property is not deleted even in case for a given
            // property both @MoveFrom and @Delete is set
            property.setDelete(false);

            // record successful move
            if (isMove) {
                changes.add(Modification.onMoved(source, propPath));
            } else {
                changes.add(Modification.onCopied(source, propPath));
            }
        }
    }

    /**
     * Removes all properties listed as {@link RequestProperty#isDelete()} from
     * the resource.
     *
     * @param resolver The <code>ResourceResolver</code> used to access the
     *            resources to delete the properties.
     * @param reqProperties The map of request properties to check for
     *            properties to be removed.
     * @param response The <code>HtmlResponse</code> to be updated with
     *            information on deleted properties.
     * @throws RepositoryException Is thrown if an error occurrs checking or
     *             removing properties.
     */
    private void processDeletes(final ResourceResolver resolver,
            final Map<String, RequestProperty> reqProperties,
            final List<Modification> changes,
            final VersioningConfiguration versioningConfiguration)
    throws RepositoryException, PersistenceException {

        for (final RequestProperty property : reqProperties.values()) {

            if (property.isDelete()) {
                final Resource parent = resolver.getResource(property.getParentPath());
                if ( parent == null ) {
                    continue;
                }
                final Node parentNode = parent.adaptTo(Node.class);

                if ( parentNode != null ) {
                    this.jcrSsupport.checkoutIfNecessary(parent, changes, versioningConfiguration);

                    if (property.getName().equals("jcr:mixinTypes")) {

                        // clear all mixins
                        for (NodeType mixin : parentNode.getMixinNodeTypes()) {
                            parentNode.removeMixin(mixin.getName());
                        }

                    } else {
                        if ( parentNode.hasProperty(property.getName())) {
                            parentNode.getProperty(property.getName()).remove();
                        } else if ( parentNode.hasNode(property.getName())) {
                            parentNode.getNode(property.getName()).remove();
                        }
                    }

                } else {
                    final ValueMap vm = parent.adaptTo(ModifiableValueMap.class);
                    if ( vm == null ) {
                        throw new PersistenceException("Resource '" + parent.getPath() + "' is not modifiable.");
                    }
                    vm.remove(property.getName());
                }

                changes.add(Modification.onDeleted(property.getPath()));
            }
        }

    }

    /**
     * Writes back the content
     *
     * @throws RepositoryException if a repository error occurs
     * @throws PersistenceException if a persistence error occurs
     */
    private void writeContent(final ResourceResolver resolver,
            final Map<String, RequestProperty> reqProperties,
            final List<Modification> changes,
            final VersioningConfiguration versioningConfiguration)
    throws RepositoryException, PersistenceException {

        final SlingPropertyValueHandler propHandler = new SlingPropertyValueHandler(
            dateParser, this.jcrSsupport, changes);

        for (final RequestProperty prop : reqProperties.values()) {
            if (prop.hasValues()) {
                final Resource parent = deepGetOrCreateResource(resolver,
                    prop.getParentPath(), reqProperties, changes, versioningConfiguration);

                this.jcrSsupport.checkoutIfNecessary(parent, changes, versioningConfiguration);

                // skip jcr special properties
                if (prop.getName().equals("jcr:primaryType")
                    || prop.getName().equals("jcr:mixinTypes")) {
                    continue;
                }

                if (prop.isFileUpload()) {
                    uploadHandler.setFile(parent, prop, changes);
                } else {
                    propHandler.setProperty(parent, prop);
                }
            }
        }
    }
}
