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

import java.util.ArrayList;
import java.util.List;

import org.apache.avalon.framework.service.Serviceable;
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.Publication;
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.repository.RepositoryItemFactory;
import org.apache.lenya.cms.site.AbstractSiteManager;
import org.apache.lenya.cms.site.Link;
import org.apache.lenya.cms.site.NodeSet;
import org.apache.lenya.cms.site.SiteException;
import org.apache.lenya.cms.site.SiteNode;
import org.apache.lenya.cms.site.SiteStructure;

/**
 * A tree-based site manager.
 * 
 * @version $Id: TreeSiteManager.java 208766 2005-07-01 16:05:00Z andreas $
 */
public class TreeSiteManager extends AbstractSiteManager implements Serviceable {

    /**
     * Ctor.
     */
    public TreeSiteManager() {
        // do nothing
    }

    /**
     * Returns the sitetree for a specific area of this publication. Sitetrees are created on demand
     * and are cached.
     * 
     * @param map The document identity map.
     * @param publication The publication.
     * @param area The area.
     * @return A site tree.
     * @throws SiteException if an error occurs.
     */
    public DefaultSiteTree getTree(DocumentFactory map, Publication publication, String area)
            throws SiteException {

        String key = getKey(publication, area);
        DefaultSiteTree sitetree;
        RepositoryItemFactory factory = new SiteTreeFactory(this.manager, getLogger());
        try {
            sitetree = (DefaultSiteTree) map.getSession().getRepositoryItem(factory, key);
        } catch (Exception e) {
            throw new SiteException(e);
        }

        return sitetree;
    }

    protected DefaultSiteTree getTree(Document document) throws SiteException {
        return getTree(document.getFactory(), document.getPublication(), document.getArea());
    }

    /**
     * Returns the ancestors of a resource, beginning with the parent.
     * 
     * @param node The resource.
     * @return A list of resources.
     * @throws SiteException if an error occurs.
     */
    protected List getAncestors(SiteNode node) throws SiteException {
        List ancestors = new ArrayList();
        SiteNode parent = null;
        try {
            if (!node.isTopLevel()) {
                parent = node.getParent();
                ancestors.add(parent);
                ancestors.addAll(getAncestors(parent));
            }
        } catch (Exception e) {
            throw new SiteException(e);
        }
        return ancestors;
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#requires(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.site.SiteNode, org.apache.lenya.cms.site.SiteNode)
     */
    public boolean requires(DocumentFactory map, SiteNode dependingResource,
            SiteNode requiredResource) throws SiteException {
        return getAncestors(dependingResource).contains(requiredResource);
    }

    public DocumentLocator[] getRequiredResources(DocumentFactory map, final DocumentLocator loc)
            throws SiteException {
        
        List ancestors = new ArrayList();
        DocumentLocator locator = loc;
        while (locator.getParent() != null) {
            DocumentLocator parent = locator.getParent();
            ancestors.add(parent);
            locator = parent;
        }
        return (DocumentLocator[]) ancestors.toArray(new DocumentLocator[ancestors.size()]);
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getRequiringResources(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.site.SiteNode)
     */
    public SiteNode[] getRequiringResources(DocumentFactory map, SiteNode resource)
            throws SiteException {

        if (getLogger().isDebugEnabled()) {
            getLogger().debug("Obtaining requiring resources of [" + resource + "]");
        }

        NodeSet nodes = new NodeSet(this.manager);
        Publication pub = resource.getStructure().getPublication();
        String area = resource.getStructure().getArea();
        SiteTree tree = getTree(map, pub, area);

        SiteTreeNodeImpl node = (SiteTreeNodeImpl) tree.getNode(resource.getPath());
        if (node != null) {
            List preOrder = node.preOrder();

            // remove original resource (does not require itself)
            preOrder.remove(0);

            for (int i = 0; i < preOrder.size(); i++) {
                SiteTreeNode descendant = (SiteTreeNode) preOrder.get(i);
                nodes.add(descendant);
            }

            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Obtaining requiring resources completed.");
            }
        }

        return nodes.getNodes();
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#contains(org.apache.lenya.cms.publication.Document)
     */
    public boolean contains(Document resource) throws SiteException {
        SiteTree tree = getTree(resource);
        return tree.containsByUuid(resource.getUUID(), resource.getLanguage());
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#containsInAnyLanguage(org.apache.lenya.cms.publication.Document)
     */
    public boolean containsInAnyLanguage(Document resource) throws SiteException {
        SiteTree tree = getTree(resource);
        return tree.containsInAnyLanguage(resource.getUUID());
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#copy(org.apache.lenya.cms.publication.Document,
     *      org.apache.lenya.cms.publication.Document)
     */
    public void copy(Document sourceDocument, Document destinationDocument) throws SiteException {
        DefaultSiteTree destinationTree = getTree(destinationDocument);

        try {
            SiteTreeNode sourceNode = (SiteTreeNode) sourceDocument.getLink().getNode();

            SiteTreeNode[] siblings = sourceNode.getNextSiblings();
            SiteNode parent = sourceNode.getParent();
            String parentId = "";
            if (parent != null) {
                parentId = parent.getPath();
            }
            SiteTreeNode sibling = null;
            String siblingPath = null;

            // same UUID -> insert at the same position
            if (sourceDocument.getUUID().equals(destinationDocument.getUUID())) {
                for (int i = 0; i < siblings.length; i++) {
                    String path = parentId + "/" + siblings[i].getName();
                    sibling = (SiteTreeNode) destinationTree.getNode(path);
                    if (sibling != null) {
                        siblingPath = path;
                        break;
                    }
                }
            }

            if (!sourceNode.hasLink(sourceDocument.getLanguage())) {
                // the node that we're trying to publish
                // doesn't have this language
                throw new SiteException("The node " + sourceDocument.getPath()
                        + " doesn't contain a label for language " + sourceDocument.getLanguage());
            }
            Link link = sourceNode.getLink(sourceDocument.getLanguage());
            SiteTreeNode destinationNode = (SiteTreeNode) destinationTree.getNode(destinationDocument.getPath());
            if (destinationNode == null) {
                if (siblingPath == null) {
                    destinationTree.addNode(destinationDocument.getPath(),
                            destinationDocument.getUUID(),
                            sourceNode.isVisible(),
                            sourceNode.getHref(),
                            sourceNode.getSuffix(),
                            sourceNode.hasLink());
                    destinationTree.addLabel(destinationDocument.getPath(),
                            destinationDocument.getLanguage(),
                            link.getLabel());
                } else {
                    destinationTree.addNode(destinationDocument.getPath(),
                            destinationDocument.getUUID(),
                            sourceNode.isVisible(),
                            sourceNode.getHref(),
                            sourceNode.getSuffix(),
                            sourceNode.hasLink(),
                            siblingPath);
                    destinationTree.addLabel(destinationDocument.getPath(),
                            destinationDocument.getLanguage(),
                            link.getLabel());
                }

            } else {
                // if the node already exists in the live
                // tree simply insert the label in the
                // live tree
                destinationDocument.getLink().setLabel(link.getLabel());
            }
        } catch (DocumentException e) {
            throw new SiteException(e);
        }

    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#setVisibleInNav(org.apache.lenya.cms.publication.Document,
     *      boolean)
     */
    public void setVisibleInNav(Document document, boolean visibleInNav) throws SiteException {
        SiteTree tree = getTree(document);
        try {
            tree.getNode(document.getPath()).setVisible(visibleInNav);
        } catch (DocumentException e) {
            throw new SiteException(e);
        }
    }

    /**
     * Returns the label object of a document.
     * 
     * @param document The document.
     * @return A label.
     * @throws SiteException if an error occurs.
     */
    protected Link getLabelObject(Document document) throws SiteException {
        Link label = null;
        SiteTree siteTree = getTree(document);
        if (siteTree != null) {
            SiteTreeNode node = (SiteTreeNode) siteTree.getByUuid(document.getUUID(),
                    document.getLanguage()).getNode();
            if (node == null) {
                throw new SiteException("Node for document [" + document + "] does not exist!");
            }
            label = (Link) node.getLink(document.getLanguage());
        }

        if (label == null) {
            throw new SiteException("The label of document [" + document + "] is null!");
        }

        return label;
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getDocuments(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.publication.Publication, java.lang.String)
     */
    public Document[] getDocuments(DocumentFactory map, Publication publication, String area)
            throws SiteException {
        try {
            SiteTreeNodeImpl root = (SiteTreeNodeImpl) getTree(map, publication, area).getNode("/");
            List allNodes = root.preOrder();
            List documents = new ArrayList();

            for (int i = 1; i < allNodes.size(); i++) {
                SiteTreeNode node = (SiteTreeNode) allNodes.get(i);
                Document doc = map.get(publication, area, node.getUuid());
                String[] languages = doc.getLanguages();
                for (int l = 0; l < languages.length; l++) {
                    documents.add(doc.getTranslation(languages[l]));
                }
            }
            return (Document[]) documents.toArray(new Document[documents.size()]);
        } catch (Exception e) {
            throw new SiteException(e);
        }
    }

    public void add(String path, Document document) throws SiteException {

        if (contains(document)) {
            throw new SiteException("The document [" + document + "] is already contained!");
        }
        DefaultSiteTree tree = getTree(document);

        SiteTreeNode node;
        if (!tree.contains(path)) {
            // done for side effect of calling addNodNode, not the resulting return value
            node = tree.addNode(path, document.getUUID(), true, null, null, false);
        } else {
            node = (SiteTreeNode) tree.getNode(path);
            if (node.getUuid() != null) {
                ((SiteTreeNodeImpl) node).setUUID(document.getUUID());
            }
        }
        tree.addLabel(path, document.getLanguage(), "");
    }

    public void set(String path, Document document) throws SiteException {

        if (contains(document)) {
            throw new SiteException("The document [" + document + "] is already contained!");
        }
        DefaultSiteTree tree = getTree(document);
        SiteTreeNodeImpl node = (SiteTreeNodeImpl) tree.getNode(path);
        node.setUUID(document.getUUID());
        tree.changed();
    }

    /**
     * @param publication The publication.
     * @param area The area.
     * @return The key to store sitetree objects in the identity map.
     */
    protected String getKey(Publication publication, String area) {
        return publication.getId() + ":" + area;
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getSiteStructure(org.apache.lenya.cms.publication.DocumentFactory,
     *      org.apache.lenya.cms.publication.Publication, java.lang.String)
     */
    public SiteStructure getSiteStructure(DocumentFactory map, Publication publiation, String area)
            throws SiteException {
        return getTree(map, publiation, area);
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#getAvailableLocator(DocumentFactory,
     *      org.apache.lenya.cms.publication.DocumentLocator)
     */
    public DocumentLocator getAvailableLocator(DocumentFactory factory, DocumentLocator locator)
            throws SiteException {
        return DocumentLocator.getLocator(locator.getPublicationId(),
                locator.getArea(),
                computeUniquePath(factory, locator),
                locator.getLanguage());
    }

    /**
     * compute an unique document id
     * @param factory The factory.
     * @param locator The locator.
     * @return the unique documentid
     * @throws SiteException if an error occurs.
     */
    protected String computeUniquePath(DocumentFactory factory, DocumentLocator locator)
            throws SiteException {
        String path = locator.getPath();

        Publication pub;
        try {
            pub = factory.getPublication(locator.getPublicationId());
        } catch (PublicationException e) {
            throw new SiteException(e);
        }
        SiteTree tree = getTree(factory, pub, locator.getArea());

        String suffix = null;
        int version = 0;
        String idwithoutsuffix = null;

        if (tree.contains(path)) {
            int n = path.lastIndexOf("/");
            String lastToken = "";
            String substring = path;
            if ((n < path.length()) && (n > 0)) {
                lastToken = path.substring(n);
                substring = path.substring(0, n);
            }

            int l = lastToken.length();
            int index = lastToken.lastIndexOf("-");
            if (0 < index && index < l) {
                suffix = lastToken.substring(index + 1);
                idwithoutsuffix = substring + lastToken.substring(0, index);
                version = Integer.parseInt(suffix);
            } else {
                idwithoutsuffix = substring + lastToken;
            }

            while (tree.contains(path)) {
                version = version + 1;
                path = idwithoutsuffix + "-" + version;
            }
        }

        return path;
    }

    public boolean isVisibleInNav(Document document) throws SiteException {
        SiteTree tree = getTree(document);
        try {
            return tree.getNode(document.getPath()).isVisible();
        } catch (DocumentException e) {
            throw new SiteException(e);
        }
    }

    protected String getPath(DocumentFactory factory, Publication pub, String area, String uuid,
            String language) throws SiteException {
        SiteTree tree = getTree(factory, pub, area);
        SiteNode node = tree.getByUuid(uuid, language).getNode();
        if (node == null) {
            throw new SiteException("No node found for [" + pub.getId() + ":" + area + ":" + uuid
                    + ":" + language + "]");
        }
        return node.getPath();
    }

    protected String getUUID(DocumentFactory factory, Publication pub, String area, String path)
            throws SiteException {
        SiteTree tree = getTree(factory, pub, area);
        SiteNode node = tree.getNode(path);
        if (node == null) {
            throw new SiteException("No node found for [" + pub.getId() + ":" + area + ":" + path
                    + "]");
        }
        return node.getUuid();
    }

    protected boolean contains(DocumentFactory factory, DocumentLocator locator)
            throws SiteException {
        Publication pub;
        try {
            pub = factory.getPublication(locator.getPublicationId());
        } catch (PublicationException e) {
            throw new SiteException(e);
        }
        SiteTree tree = getTree(factory, pub, locator.getArea());
        if (tree.contains(locator.getPath())) {
            SiteNode node = tree.getNode(locator.getPath());
            return node.hasLink(locator.getLanguage());
        } else {
            return false;
        }
    }

}
