/*
 * 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.lenya.cms.site.usecases;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.cocoon.processing.ProcessInfoProvider;
import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.lenya.ac.Identity;
import org.apache.lenya.ac.User;
import org.apache.lenya.cms.metadata.MetaData;
import org.apache.lenya.cms.metadata.MetaDataException;
import org.apache.lenya.cms.metadata.dublincore.DublinCore;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentManager;
import org.apache.lenya.cms.publication.Node;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.ResourceType;
import org.apache.lenya.cms.publication.ResourceTypeResolver;
import org.apache.lenya.cms.publication.URLInformation;
import org.apache.lenya.cms.site.SiteStructure;
import org.apache.lenya.cms.usecase.AbstractUsecase;
import org.apache.lenya.cms.usecase.UsecaseException;

/**
 * <p>
 * Abstract superclass for usecases to create a document.
 * </p>
 * <p>
 * You can pass the following parameters into the usecase:
 * </p>
 * <ul>
 * <li><strong>path</strong> - the path of the document to create (optional)</li>
 * </ul>
 * 
 * @version $Id$
 */
public abstract class Create extends AbstractUsecase {

    protected static final String RESOURCE_TYPES = "resourceTypes";
    protected static final String LANGUAGE = "language";
    protected static final String LANGUAGES = "languages";
    protected static final String PATH = "path";
    protected static final String NODE_NAME = "nodeName";
    protected static final String VISIBLEINNAV = "visibleInNav";
    protected static final String SAMPLE = "sample";
    protected static final String SAMPLES = "samples";

    private DocumentManager documentManager;
    private ResourceTypeResolver resourceTypeResolver;

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#doCheckPreconditions()
     */
    protected void doCheckPreconditions() throws Exception {
        super.doCheckPreconditions();

        if (!getArea().equals(Publication.AUTHORING_AREA)) {
            addErrorMessage("This usecase can only be invoked in the authoring area!");
        }
    }

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#getNodesToLock()
     */
    protected Node[] getNodesToLock() throws UsecaseException {
        try {
            SiteStructure structure = getPublication().getArea(getArea()).getSite();
            Node[] nodes = { structure };
            return nodes;
        } catch (Exception e) {
            throw new UsecaseException(e);
        }
    }

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#doCheckExecutionConditions()
     */
    protected void doCheckExecutionConditions() throws Exception {
        String navigationTitle = getDublinCoreParameter(DublinCore.ELEMENT_TITLE);
        if (navigationTitle.trim().equals("")) {
            addErrorMessage("missing-navigation-title");
        }

        if (getInitialDocument() == null) {
            String[] samples = (String[]) getParameter(SAMPLES);
            String sample = getParameterAsString(SAMPLE);
            if (samples != null && samples.length > 1 && (sample == null || sample.equals(""))) {
                addErrorMessage("missing-page-layout");
            }
        }

        if (isPathValid()) {
            String path = getNewDocumentPath();
            SiteStructure site = getPublication().getArea(getArea()).getSite();
            if (!createVersion() && site.contains(path)) {
                String[] params = { path };
                addErrorMessage("path-already-exists", params);
            }
        }

        String doctypeName = getDocumentTypeName();
        if (getParameterAsString(SAMPLE) == null && doctypeName != null) {
            initSampleParameters();
        }
    }

    /**
     * This method is used by {@link #doCheckExecutionConditions()} to check if the path entered by
     * the user is valid. If not, checking the existence of the new document in the site structure
     * is omitted because this operation could cause errors.
     * @return A boolean value.
     */
    protected boolean isPathValid() {
        return true;
    }

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#doExecute()
     */
    protected void doExecute() throws Exception {
        super.doExecute();

        // create new document
        ResourceType resourceType = null;

        String language = getParameterAsString(LANGUAGE);
        Document initialDocument = getInitialDocument();

        Document document;

        String title = getDublinCoreParameter(DublinCore.ELEMENT_TITLE).trim();

        if (createVersion()) {
            document = documentManager.addVersion(initialDocument, getArea(), language, true);
            document.getLink().setLabel(title);
        } else {
            if (initialDocument == null) {
                resourceType = getResourceTypeResolver().getResourceType(getDocumentTypeName());
                String sampleName = getParameterAsString(SAMPLE, resourceType.getSampleNames()[0]);
                ResourceType.Sample sample = resourceType.getSample(sampleName);
                document = documentManager.add(resourceType, sample.getUri(),
                        getPublication(), getArea(), getNewDocumentPath(), language,
                        getSourceExtension(), title, getVisibleInNav());
                document.setMimeType(sample.getMimeType());
            } else {
                document = documentManager.add(initialDocument, getArea(), getNewDocumentPath(),
                        language, getSourceExtension(), title, getVisibleInNav());
            }
        }

        setMetaData(document);

        // the location to navigate to after completion of usecase
        setDefaultTargetURL(document.getCanonicalWebappURL());
    }

    protected String getDublinCoreParameter(String name) {
        Object param = getParameter(DUBLIN_CORE_PREFIX + name);
        if (param != null && getParameter(DUBLIN_CORE_PREFIX + name).getClass().isArray()) {
            String[] values = (String[]) getParameter(DUBLIN_CORE_PREFIX + name);
            StringBuffer paramValue = new StringBuffer();
            for (int i = 0; i < values.length; i++) {
                String value = values[i];
                if (i > 0)
                    paramValue.append(',').append(value);
                else
                    paramValue.append(value);
            }
            return paramValue.toString();
        }
        return getParameterAsString(DUBLIN_CORE_PREFIX + name, null);
    }

    protected void setDublinCoreParameter(String name, String value) {
        setParameter(DUBLIN_CORE_PREFIX + name, value);
    }

    protected abstract boolean createVersion();

    /**
     * @return the extension to use for the document source.
     */
    protected abstract String getSourceExtension();

    /**
     * @return the name of the document being created in the usecase
     */
    protected abstract String getNewDocumentName();

    /**
     * @return the id of the new document being created in the usecase
     */
    protected abstract String getNewDocumentPath();

    /**
     * If the document created in the usecase shall have initial contents copied from an existing
     * document, construct that document in this method.
     * 
     * @return A document.
     */
    protected Document getInitialDocument() {
        return null;
    }

    /**
     * @return The type of the created document.
     */
    protected abstract String getDocumentTypeName();

    protected static final String DUBLIN_CORE_PREFIX = "dublincore.";

    /**
     * Sets the meta data of the created document.
     * 
     * @param document The document.
     * @throws MetaDataException if an error occurs.
     */
    protected void setMetaData(Document document) throws MetaDataException {

        if (document == null)
            throw new IllegalArgumentException("parameter document may not be null");

        MetaData dcMetaData = document.getMetaData(DublinCore.DC_NAMESPACE);
        String[] dcKeys = dcMetaData.getAvailableKeys();

        for (int i = 0; i < dcKeys.length; i++) {
            String param = getDublinCoreParameter(dcKeys[i]);
            if (param != null) {
                dcMetaData.setValue(dcKeys[i], param);
            }
        }

    }

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#initParameters()
     */
    protected void initParameters() {
        super.initParameters();

        ProcessInfoProvider process = (ProcessInfoProvider) WebAppContextUtils
                .getCurrentWebApplicationContext().getBean(ProcessInfoProvider.ROLE);
        HttpServletRequest request = process.getRequest();
        HttpSession session = request.getSession(false);
        Identity identity = (Identity) session.getAttribute(Identity.class.getName());
        User user = identity.getUser();
        if (user != null) {
            setDublinCoreParameter(DublinCore.ELEMENT_CREATOR, user.getId());
        } else {
            setDublinCoreParameter(DublinCore.ELEMENT_CREATOR, "");
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        setDublinCoreParameter(DublinCore.ELEMENT_DATE, format.format(new GregorianCalendar()
                .getTime()));

        String doctypeName = getDocumentTypeName();
        if (doctypeName != null) {
            initSampleParameters();
            setParameter(RESOURCE_TYPES, Collections.EMPTY_LIST);
        } else {
            String[] resourceTypes = getPublication().getResourceTypeNames();
            setParameter(RESOURCE_TYPES, Arrays.asList(resourceTypes));
        }
    }

    protected void initSampleParameters() {
        ResourceType resourceType = null;
        try {
            resourceType = getResourceTypeResolver().getResourceType(getDocumentTypeName());
            String[] samples = resourceType.getSampleNames();
            if (samples.length == 0) {
                addErrorMessage("The resource type [" + resourceType.getName()
                        + "] doesn't provide any samples!");
            } else {
                setParameter(SAMPLES, samples);
                String presetSample = getParameterAsString(SAMPLE);
                if (presetSample == null) {
                    setParameter(SAMPLE, samples[0]);
                } else {
                    List sampleList = Arrays.asList(samples);
                    if (!sampleList.contains(presetSample)) {
                        getLogger().warn(
                                "Sample [" + presetSample + "] not defined, using default sample.");
                        setParameter(SAMPLE, samples[0]);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @return The source document or <code>null</code> if the usecase was not invoked on a
     *         document.
     */
    protected Document getSourceDocument() {
        Document document = null;
        String url = getSourceURL();
        try {
            if (getSession().getUriHandler().isDocument(url)) {
                document = getSession().getUriHandler().getDocument(url);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return document;
    }

    /**
     * @return The new document.
     */
    protected Document getNewDocument() {
        try {
            String path = getNewDocumentPath();
            String language = getParameterAsString(LANGUAGE);
            return getPublication().getArea(getArea()).getSite().getNode(path).getLink(language)
                    .getDocument();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @return The area without the "info-" prefix.
     */
    public String getArea() {
        URLInformation info = new URLInformation(getSourceURL());
        return info.getArea();
    }

    /**
     * @return the visibleInNav Attribute of the document being created in the usecase
     */
    protected boolean getVisibleInNav() {
        if (getParameterAsString(VISIBLEINNAV).equals("false")) {
            return false;
        }
        return true;
    }

    protected DocumentManager getDocumentManager() {
        return documentManager;
    }

    /**
     * TODO: Bean wiring
     */
    public void setDocumentManager(DocumentManager documentManager) {
        this.documentManager = documentManager;
    }

    protected ResourceTypeResolver getResourceTypeResolver() {
        return resourceTypeResolver;
    }

    /**
     * TODO: Bean wiring
     */
    public void setResourceTypeResolver(ResourceTypeResolver resourceTypeResolver) {
        this.resourceTypeResolver = resourceTypeResolver;
    }

}
