/*
 * 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.workflow.usecases;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.environment.Request;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.Identifiable;
import org.apache.lenya.ac.User;
import org.apache.lenya.cms.ac.PolicyUtil;
import org.apache.lenya.cms.linking.LinkManager;
import org.apache.lenya.cms.linking.LinkResolver;
import org.apache.lenya.cms.linking.LinkTarget;
import org.apache.lenya.cms.metadata.dublincore.DublinCoreHelper;
import org.apache.lenya.cms.observation.RepositoryEvent;
import org.apache.lenya.cms.observation.RepositoryEventFactory;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentException;
import org.apache.lenya.cms.publication.DocumentFactory;
import org.apache.lenya.cms.publication.DocumentLocator;
import org.apache.lenya.cms.publication.DocumentManager;
import org.apache.lenya.cms.publication.Proxy;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.site.Link;
import org.apache.lenya.cms.site.SiteException;
import org.apache.lenya.cms.site.SiteManager;
import org.apache.lenya.cms.site.SiteNode;
import org.apache.lenya.cms.site.SiteStructure;
import org.apache.lenya.cms.usecase.UsecaseException;
import org.apache.lenya.cms.usecase.scheduling.UsecaseScheduler;
import org.apache.lenya.cms.workflow.WorkflowUtil;
import org.apache.lenya.cms.workflow.usecases.InvokeWorkflow;
import org.apache.lenya.notification.Message;
import org.apache.lenya.notification.NotificationEventDescriptor;
import org.apache.lenya.notification.NotificationException;
import org.apache.lenya.workflow.Version;
import org.apache.lenya.workflow.Workflowable;

/**
 * Publish usecase handler.
 * 
 * @version $Id$
 */
public class Publish extends InvokeWorkflow {

    protected static final String MESSAGE_SUBJECT = "notification-message";
    protected static final String MESSAGE_DOCUMENT_PUBLISHED = "document-published";
    protected static final String SCHEDULE = "schedule";
    protected static final String SCHEDULE_TIME = "schedule.time";
    protected static final String SEND_NOTIFICATION = "sendNotification";
    protected static final String UNPUBLISHED_LINKS = "unpublishedLinks";

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

        if (hasErrors() || getSourceDocument() == null) {
            return;
        }

        Date now = new GregorianCalendar().getTime();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        setParameter(SCHEDULE_TIME, format.format(now));

        setParameter(SEND_NOTIFICATION, Boolean.TRUE);
        
        setParameter(UNPUBLISHED_LINKS, new LinkList(this.manager, getSourceDocument()));
        
    }
    
    protected boolean hasBrokenLinks() {
        LinkManager linkMgr = null;
        LinkResolver resolver = null;
        try {
            linkMgr = (LinkManager) this.manager.lookup(LinkManager.ROLE);
            resolver = (LinkResolver) this.manager.lookup(LinkResolver.ROLE);
            org.apache.lenya.cms.linking.Link[] links = linkMgr.getLinksFrom(getSourceDocument());
            for (int i = 0; i < links.length; i++) {
                LinkTarget target = resolver.resolve(getSourceDocument(), links[i].getUri());
                if (!target.exists()) {
                    return true;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (linkMgr != null) {
                this.manager.release(linkMgr);
            }
            if (resolver != null) {
                this.manager.release(resolver);
            }
        }
        return false;
    }
    
    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#getNodesToLock()
     */
    protected org.apache.lenya.cms.repository.Node[] getNodesToLock() throws UsecaseException {
        try {
            List nodes = new ArrayList();

            Document doc = getSourceDocument();
            if(doc != null) {
                nodes.add(doc.getRepositoryNode());
                
                // lock the authoring site to avoid having live nodes for which no corresponding
                // authoring node exists
                nodes.add(doc.area().getSite().getRepositoryNode());
                
                // lock the live site to avoid overriding changes made by others
                SiteStructure liveSite = doc.getPublication().getArea(Publication.LIVE_AREA).getSite();
                nodes.add(liveSite.getRepositoryNode());
            }

            return (org.apache.lenya.cms.repository.Node[]) nodes
                    .toArray(new org.apache.lenya.cms.repository.Node[nodes.size()]);

        } catch (Exception e) {
            throw new UsecaseException(e);
        }
    }

    /**
     * Checks if the workflow event is supported and the parent of the document
     * exists in the live area.
     * 
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#doCheckPreconditions()
     */
    protected void doCheckPreconditions() throws Exception {
        super.doCheckPreconditions();
        if (!hasErrors()) {

            Document document = getSourceDocument();

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

            Publication publication = document.getPublication();
            DocumentFactory map = document.getFactory();
            SiteStructure liveSite = publication.getArea(Publication.LIVE_AREA).getSite();

            List missingDocuments = new ArrayList();

            ServiceSelector selector = null;
            SiteManager siteManager = null;
            try {
                selector = (ServiceSelector) this.manager.lookup(SiteManager.ROLE + "Selector");
                siteManager = (SiteManager) selector.select(publication.getSiteManagerHint());

                if (!liveSite.contains(document.getPath())) {
                    DocumentLocator liveLoc = document.getLocator().getAreaVersion(
                            Publication.LIVE_AREA);
                    DocumentLocator[] requiredNodes = siteManager
                            .getRequiredResources(map, liveLoc);
                    for (int i = 0; i < requiredNodes.length; i++) {
                        String path = requiredNodes[i].getPath();
                        if (!liveSite.contains(path)) {
                            Link link = getExistingLink(path, document);
                            if (link != null) {
                                missingDocuments.add(link.getDocument());
                            }
                        }

                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (selector != null) {
                    if (siteManager != null) {
                        selector.release(siteManager);
                    }
                    this.manager.release(selector);
                }
            }

            if (!missingDocuments.isEmpty()) {
                addErrorMessage("publish-missing-documents");
                for (Iterator i = missingDocuments.iterator(); i.hasNext();) {
                    Document doc = (Document) i.next();
                    /*
                     * This doesn't work yet, see
                     * https://issues.apache.org/jira/browse/COCOON-2057
                     * String[] params = { doc.getCanonicalWebappURL(),
                     * doc.getPath() + " (" + doc.getLanguage() + ")" };
                     */
                    String[] params = { doc.getPath() + ":" + doc.getLanguage(),
                            DublinCoreHelper.getTitle(doc, true) };
                    addErrorMessage("missing-document", params);
                }
            }
            
            if (hasBrokenLinks()) {
                addInfoMessage("publish-broken-links");
            }
        }
    }

    /**
     * Returns a link of a certain node, preferably in the document's language,
     * or <code>null</code> if the node has no links.
     * @param path The path of the node.
     * @param document The document.
     * @return A link or <code>null</code>.
     * @throws SiteException if an error occurs.
     */
    protected Link getExistingLink(String path, Document document) throws SiteException {
        SiteNode node = document.area().getSite().getNode(path);
        Link link = null;
        String uuid = node.getUuid();
        if (uuid != null && uuid.equals(document.getUUID())) {
            if (node.hasLink(document.getLanguage())) {
                link = node.getLink(document.getLanguage());
            } else if (node.getLanguages().length > 0) {
                link = node.getLink(node.getLanguages()[0]);
            }
        }
        return link;
    }

    protected void doCheckExecutionConditions() throws Exception {
        super.doCheckExecutionConditions();
        boolean schedule = Boolean.valueOf(getBooleanCheckboxParameter(SCHEDULE)).booleanValue();
        if (schedule) {
            String dateString = getParameterAsString(SCHEDULE_TIME);
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                format.parse(dateString);
            } catch (ParseException e) {
                addErrorMessage("scheduler-date-format-invalid");
            }
        }
    }

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

        boolean schedule = Boolean.valueOf(getBooleanCheckboxParameter(SCHEDULE)).booleanValue();
        if (schedule) {
            deleteParameter(SCHEDULE);
            String dateString = getParameterAsString(SCHEDULE_TIME);
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            UsecaseScheduler scheduler = null;
            try {
                Date date = format.parse(dateString);
                scheduler = (UsecaseScheduler) this.manager.lookup(UsecaseScheduler.ROLE);
                scheduler.schedule(this, date);
            } catch (ParseException e) {
                addErrorMessage("scheduler-date-format-invalid");
            } finally {
                if (scheduler != null) {
                    this.manager.release(scheduler);
                }
            }
        } else {
            super.doExecute();
            publish(getSourceDocument());
        }
    }

    protected void publish(Document authoringDocument) throws DocumentException, SiteException,
            PublicationException {

        createAncestorNodes(authoringDocument);

        DocumentManager documentManager = null;

        try {
            documentManager = (DocumentManager) this.manager.lookup(DocumentManager.ROLE);
            documentManager.copyToArea(authoringDocument, Publication.LIVE_AREA);

            boolean notify = Boolean.valueOf(getBooleanCheckboxParameter(SEND_NOTIFICATION))
                    .booleanValue();
            if (notify) {
                sendNotification(authoringDocument);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (documentManager != null) {
                this.manager.release(documentManager);
            }
        }
    }

    protected void sendNotification(Document authoringDocument) throws NotificationException,
            DocumentException, AccessControlException {
        User sender = getSession().getIdentity().getUser();

        Workflowable workflowable = WorkflowUtil.getWorkflowable(this.manager, getSession(),
                getLogger(), authoringDocument);
        Version versions[] = workflowable.getVersions();
        Version version = versions[versions.length - 2];

        // we assume that the document has been submitted, otherwise we do
        // nothing
        if (version.getEvent().equals("submit")) {

            String userId = version.getUserId();
            User user = PolicyUtil.getUser(this.manager, authoringDocument.getCanonicalWebappURL(),
                    userId, getLogger());

            Identifiable[] recipients = { user };

            Document liveVersion = authoringDocument.getAreaVersion(Publication.LIVE_AREA);
            String url;

            Proxy proxy = liveVersion.getPublication().getProxy(liveVersion, false);
            if (proxy != null) {
                url = proxy.getURL(liveVersion);
            } else {
                Request request = ContextHelper.getRequest(this.context);
                final String serverUrl = "http://" + request.getServerName() + ":"
                        + request.getServerPort();
                final String webappUrl = liveVersion.getCanonicalWebappURL();
                url = serverUrl + request.getContextPath() + webappUrl;
            }
            String[] params = { url };
            Message message = new Message(MESSAGE_SUBJECT, new String[0],
                    MESSAGE_DOCUMENT_PUBLISHED, params, sender, recipients);

            NotificationEventDescriptor descriptor = new NotificationEventDescriptor(message);
            RepositoryEvent event = RepositoryEventFactory.createEvent(this.manager, getSession(),
                    getLogger(), descriptor);
            getSession().enqueueEvent(event);
        }
    }

    protected void createAncestorNodes(Document document) throws PublicationException,
            DocumentException, SiteException {
        SiteStructure liveSite = document.getPublication().getArea(Publication.LIVE_AREA).getSite();
        String[] steps = document.getPath().substring(1).split("/");
        int s = 0;
        String path = "";
        while (s < steps.length) {
            if (!liveSite.contains(path)) {
                liveSite.add(path);
            }
            path += "/" + steps[s];
            s++;
        }
    }
    
    /**
     * A list of links originating from a document. Allows lazy loading rom the usecase view.
     */
    public static class LinkList {
        
        private Document document;
        private Document[] documents;
        private ServiceManager manager;
        
        /**
         * @param manager The manager.
         * @param doc The document to resolve the links from.
         */
        public LinkList(ServiceManager manager, Document doc) {
            this.manager = manager;
            this.document = doc;
        }
        
        /**
         * @return The link documents.
         */
        public Document[] getDocuments() {
            if (this.documents == null) {
                this.documents = getUnpublishedLinks();
            }
            return this.documents;
        }
        
        protected Document[] getUnpublishedLinks() {
            Set docs = new HashSet();
            LinkManager linkMgr = null;
            LinkResolver resolver = null;
            try {
                linkMgr = (LinkManager) this.manager.lookup(LinkManager.ROLE);
                resolver = (LinkResolver) this.manager.lookup(LinkResolver.ROLE);
                org.apache.lenya.cms.linking.Link[] links = linkMgr.getLinksFrom(this.document);
                for (int i = 0; i < links.length; i++) {
                    LinkTarget target = resolver.resolve(this.document, links[i].getUri());
                    if (target.exists()) {
                        Document doc = target.getDocument();
                        if (!doc.existsAreaVersion(Publication.LIVE_AREA)) {
                            docs.add(doc);
                        }
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (linkMgr != null) {
                    this.manager.release(linkMgr);
                }
                if (resolver != null) {
                    this.manager.release(resolver);
                }
            }
            return (Document[]) docs.toArray(new Document[docs.size()]);
        }

    }

}
