/*
 * 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.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
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;

/**
 * The <code>AbstractCopyMoveOperation</code> is the abstract base close for
 * the {@link CopyOperation} and {@link MoveOperation} classes implementing
 * common behavior.
 */
abstract class AbstractCopyMoveOperation extends AbstractPostOperation {

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

        final Resource resource = request.getResource();
        final String source = resource.getPath();

        // ensure dest is not empty/null and is absolute
        String dest = request.getParameter(SlingPostConstants.RP_DEST);
        if (dest == null || dest.length() == 0) {
            throw new IllegalArgumentException("Unable to process "
                    + getOperationName() + ". Missing destination");
        }

        // register whether the path ends with a trailing slash
        final boolean trailingSlash = dest.endsWith("/");

        // ensure destination is an absolute and normalized path
        if (!dest.startsWith("/")) {
            dest = ResourceUtil.getParent(source) + "/" + dest;
        }
        dest = ResourceUtil.normalize(dest);

        // destination parent and name
        final String dstParent = trailingSlash ? dest : ResourceUtil.getParent(dest);

        // delete destination if already exists
        if (!trailingSlash && request.getResourceResolver().getResource(dest) != null ) {

            final String replaceString = request.getParameter(SlingPostConstants.RP_REPLACE);
            final boolean isReplace = "true".equalsIgnoreCase(replaceString);
            if (!isReplace) {
                response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
                    "Cannot " + getOperationName() + " " + resource + " to "
                        + dest + ": destination exists");
                return;
            } else {
                this.jcrSsupport.checkoutIfNecessary(request.getResourceResolver().getResource(dstParent),
                        changes, versioningConfiguration);
            }

        } else {

            // check if path to destination exists and create it, but only
            // if it's a descendant of the current node
            if (!dstParent.equals("")) {
                final Resource parentResource = request.getResourceResolver().getResource(dstParent);
                if (parentResource != null ) {
                    this.jcrSsupport.checkoutIfNecessary(parentResource, changes, versioningConfiguration);
                } else {
                    response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
                        "Cannot " + getOperationName() + " " + resource + " to "
                            + dest + ": parent of destination does not exist");
                    return;
                }
            }

            // the destination is newly created, hence a create request
            response.setCreateRequest(true);
        }

        final Iterator<Resource> resources = getApplyToResources(request);
        final Resource destResource;
        if (resources == null) {

            final String dstName = trailingSlash ? null : ResourceUtil.getName(dest);
            destResource = execute(changes, resource, dstParent, dstName, versioningConfiguration);

        } else {

            // multiple applyTo requires trailing slash on destination
            if (!trailingSlash) {
                throw new IllegalArgumentException(
                    "Applying "
                        + getOperationName()
                        + " to multiple resources requires a trailing slash on the destination");
            }

            // multiple copy will never return 201/CREATED
            response.setCreateRequest(false);

            while (resources.hasNext()) {
                final Resource applyTo = resources.next();
                execute(changes, applyTo, dstParent, null, versioningConfiguration);
            }
            destResource = request.getResourceResolver().getResource(dest);

        }

        if ( destResource == null ) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND,
                    "Missing source " + resource + " for " + getOperationName());
            return;
        }
        // finally apply the ordering parameter
        this.jcrSsupport.orderNode(request, destResource, changes);
    }

    /**
     * Returns a short name to be used in log and status messages.
     * @return the name of the operation
     */
    protected abstract String getOperationName();

    /**
     * Actually executes the operation.
     *
     * @param changes the changes to execute
     * @param source The source item to act upon.
     * @param destParent The absolute path of the parent of the target item.
     * @param destName The name of the target item inside the
     *            <code>destParent</code>. If <code>null</code> the name of
     *            the <code>source</code> is used as the target item name.
     * @param versioningConfiguration the configuration for versioning
     * @return the resource which results of this operation
     * @throws PersistenceException May be thrown if an error occurs executing
     *             the operation.
     */
    protected abstract Resource execute(List<Modification> changes,
            Resource source,
            String destParent,
            String destName,
            VersioningConfiguration versioningConfiguration)
    throws PersistenceException;

}
