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

import java.util.Arrays;
import java.util.Comparator;

import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.lenya.cms.publication.DocumentFactory;

/**
 * Abstract base class for site managers.
 * 
 * @version $Id$
 */
public abstract class AbstractSiteManager extends AbstractLogEnabled implements SiteManager, Serviceable {

    protected ServiceManager manager;

    /**
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
    }
    
    /**
     * Ctor.
     * @param manager The service manager.
     */
    public AbstractSiteManager() {
    }

    /**
     * @see org.apache.lenya.cms.site.SiteManager#sortAscending(org.apache.lenya.cms.publication.util.DocumentSet)
     */
    public SiteNode[] sortAscending(SiteNode[] nodes) throws SiteException {
        if (nodes.length > 0) {

            DocumentFactory map = nodes[0].getStructure().getPublication().getFactory();
            if (!check(map, new NodeSet(this.manager, nodes))) {
                throw new SiteException("The dependence relation is not a strict partial order!");
            }

            SiteNode[] sortedNodes = (SiteNode[]) Arrays.asList(nodes).toArray(new SiteNode[nodes.length]);
            Arrays.sort(sortedNodes, new NodeComparator(map));
            return sortedNodes;
        }
        else {
            return  nodes;
        }
    }

    /**
     * Checks if the dependence relation is a strict partial order.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean check(DocumentFactory map, NodeSet set) throws SiteException {
        boolean isStrictPartialOrder = isIrreflexive(map, set) && isAntisymmetric(map, set)
                && isTransitive(map, set);
        return isStrictPartialOrder;
    }

    /**
     * Checks if the dependence relation is antisymmetric.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean isAntisymmetric(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isAntisymmetric = true;
        for (int i = 0; i < resources.length; i++) {
            for (int j = i + 1; j < resources.length; j++) {
                if (requires(map, resources[i], resources[j])
                        && requires(map, resources[j], resources[i])
                        && !(resources[i] == resources[j])) {
                    isAntisymmetric = false;
                }
            }
        }
        return isAntisymmetric;
    }

    /**
     * Checks if the dependence relation is transitive.
     * 
     * @param map The identity map to operate on.
     * @param set The document set to check.
     * @return A boolean value.
     * @throws SiteException when something went wrong.
     */
    protected boolean isTransitive(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isTransitive = true;
        for (int i = 0; i < resources.length; i++) {
            for (int j = i + 1; j < resources.length; j++) {
                for (int k = j + 1; k < resources.length; k++) {
                    if (requires(map, resources[i], resources[j])
                            && requires(map, resources[j], resources[k])
                            && !requires(map, resources[i], resources[k])) {
                        isTransitive = false;
                    }
                }
            }
        }
        return isTransitive;
    }

    /**
     * Checks if the dependence relation is irreflexive.
     * 
     * @param map The identity map to operate on.
     * @param set The document set.
     * @return A boolean value
     * @throws SiteException
     */
    protected boolean isIrreflexive(DocumentFactory map, NodeSet set) throws SiteException {
        SiteNode[] resources = set.getNodes();
        boolean isIrreflexive = true;
        for (int i = 0; i < resources.length; i++) {
            if (requires(map, resources[i], resources[i])) {
                isIrreflexive = false;
            }
        }
        return isIrreflexive;
    }

    /**
     * Compares nodes according to the dependence relation.
     */
    public class NodeComparator implements Comparator {

        /**
         * Ctor.
         * 
         * @param map The identity map to operate on.
         */
        public NodeComparator(DocumentFactory map) {
            this.map = map;
        }

        private DocumentFactory map;

        /**
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(Object arg0, Object arg1) {
            int result = 0;
            if (arg0 instanceof SiteNode && arg1 instanceof SiteNode) {
                SiteNode doc1 = (SiteNode) arg0;
                SiteNode doc2 = (SiteNode) arg1;

                try {
                    if (AbstractSiteManager.this.requires(map, doc1, doc2)) {
                        result = 1;
                    }
                    if (AbstractSiteManager.this.requires(map, doc2, doc1)) {
                        result = -1;
                    }
                } catch (SiteException e) {
                    throw new RuntimeException(e);
                }
            }
            return result;
        }
    }

}