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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.lenya.cms.metadata.Element;
import org.apache.lenya.cms.metadata.MetaData;
import org.apache.lenya.cms.metadata.MetaDataRegistry;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.repository.Node;
import org.apache.lenya.cms.site.usecases.SiteUsecase;
import org.apache.lenya.cms.usecase.UsecaseException;
import org.apache.lenya.cms.workflow.WorkflowUtil;
import org.apache.lenya.cms.workflow.usecases.UsecaseWorkflowHelper;

/**
 * Usecase to edit metadata for a resource.
 * 
 * @version $Id$
 */
public class Metadata extends SiteUsecase {

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#getNodesToLock()
     */
    protected Node[] getNodesToLock() throws UsecaseException {
        Node[] objects = new Node[0];
        if(getSourceDocument() != null) {
            objects = new Node[] { getSourceDocument().getRepositoryNode() };
        }
        return objects;
    }
    
    public static class MetaDataWrapper {
        
        private String[] values;
        private Element element;
        
        public MetaDataWrapper(Element element, String[] values) {
            this.values = values;
            this.element = element;
        }
        
        public String[] getValues() {
            return this.values;
        }
        
        public Element getElement() {
            return this.element;
        }
        
    }

    /**
     * @see org.apache.lenya.cms.usecase.AbstractUsecase#initParameters()
     */
    protected void initParameters() {
        super.initParameters();
        
        if (getSourceDocument() == null) {
            return;
        }

        MetaDataRegistry registry = null;
        try {
            registry = (MetaDataRegistry) this.manager.lookup(MetaDataRegistry.ROLE);

            List numbers = new ArrayList();
            Map num2namespace = new HashMap();
            List keyList = new ArrayList();

            String[] namespaces = registry.getNamespaceUris();

            for (int nsIndex = 0; nsIndex < namespaces.length; nsIndex++) {
                MetaData meta = getSourceDocument().getMetaData(namespaces[nsIndex]);
                String[] keys = meta.getPossibleKeys();
                for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
                    String key = "ns" + nsIndex + "." + keys[keyIndex];
                    String[] values = meta.getValues(keys[keyIndex]);
                    Element element = meta.getElementSet().getElement(keys[keyIndex]);
                    setParameter(key, new MetaDataWrapper(element, values));
                    keyList.add(key);
                }
                numbers.add("" + nsIndex);
                num2namespace.put("" + nsIndex, namespaces[nsIndex]);
            }

            setParameter("numbers", numbers);
            setParameter("namespaces", num2namespace);

            Collections.sort(keyList);
            setParameter("keys", keyList);

        } catch (Exception e) {
            getLogger().error("Unable to load meta data.", e);
            addErrorMessage("Unable to load meta data: " + e.getMessage());
        } finally {
            if (registry != null) {
                this.manager.release(registry);
            }
        }

    }

    protected void doCheckPreconditions() throws Exception {
        super.doCheckPreconditions();
        Document doc = getSourceDocument();
        if (doc == null) {
            return;
        }
        
        if (!doc.getArea().equals(Publication.AUTHORING_AREA)) {
            addErrorMessage("This usecase can only be invoked in the authoring area!");
        }
        UsecaseWorkflowHelper.checkWorkflow(this.manager, this, getEvent(), doc,
                getLogger());
    }

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

        // we need a reverse lookup to get the correct ns index:
        Map num2namespace = (Map) getParameter("namespaces");
        Map namespace2num = new HashMap();

        Iterator iter = num2namespace.keySet().iterator();
        while (iter.hasNext()) {
            String key = (String) iter.next();
            namespace2num.put(num2namespace.get(key), key);
        }

        Document document = getSourceDocument();
        String[] namespaces = document.getMetaDataNamespaceUris();

        for (int nsIndex = 0; nsIndex < namespaces.length; nsIndex++) {
            MetaData meta = document.getMetaData(namespaces[nsIndex]);
            String orgNsIndex = (String) namespace2num.get(namespaces[nsIndex]);

            String[] keys = meta.getPossibleKeys();
            for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
                String key = keys[keyIndex];
                Element element = meta.getElementSet().getElement(key);
                if (element.isEditable()) {
                    Object value = getParameter("ns" + orgNsIndex + "." + key);
                    if (value != null && value instanceof String) {
                        meta.setValue(key, (String) value);
                    }
                }
            }
        }

        WorkflowUtil.invoke(this.manager, getSession(), getLogger(), document, getEvent());
    }

    protected String getEvent() {
        return "edit";
    }

}
