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

import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;

import org.apache.cocoon.forms.formmodel.Form;
import org.apache.cocoon.forms.formmodel.FormDefinition;
import org.apache.cocoon.forms.formmodel.FormDefinitionBuilder;
import org.apache.cocoon.forms.formmodel.WidgetDefinitionBuilder;
import org.apache.cocoon.forms.formmodel.library.LibraryManager;
import org.apache.cocoon.forms.formmodel.library.LibraryManagerImpl;
import org.apache.cocoon.forms.util.DomHelper;
import org.apache.cocoon.forms.util.SimpleServiceSelector;
import org.apache.cocoon.util.location.LocationImpl;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

/**
 * Component implementing the {@link FormManager} role.
 *
 * @version $Id$
 */
public class DefaultFormManager extends AbstractLogEnabled
                                implements FormManager, Contextualizable, Serviceable, Configurable,
                                           Disposable, ThreadSafe, Component {
    // NOTE: Component is there to allow this block to run in the 2.1 branch

    private static final String PREFIX = "CocoonForms:";

    private Context avalonContext;
    protected ServiceManager manager;
    protected SimpleServiceSelector widgetDefinitionBuilderSelector;
    protected CacheManager cacheManager;

    protected LibraryManagerImpl libraryManager;

    //
    // Lifecycle
    //

    public DefaultFormManager() {
        widgetDefinitionBuilderSelector = new SimpleServiceSelector("widget", WidgetDefinitionBuilder.class);
        libraryManager = new LibraryManagerImpl();
    }

    public void enableLogging(Logger logger) {
        super.enableLogging(logger);
        widgetDefinitionBuilderSelector.enableLogging(getLogger());
        libraryManager.enableLogging(getLogger().getChildLogger("library"));
    }

    public void contextualize(Context context) throws ContextException {
        this.avalonContext = context;
        widgetDefinitionBuilderSelector.contextualize(avalonContext);
    }

    /** Temporary internal method, don't rely on it's existence! Needed to access the context from flowscript. */
    // FIXME (SW). Extending the FOM is needed.
    public Context getAvalonContext() {
        return this.avalonContext;
    }

    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
        this.cacheManager = (CacheManager) manager.lookup(CacheManager.ROLE);
        widgetDefinitionBuilderSelector.service(new FormServiceManager());
        libraryManager.service(new FormServiceManager());
    }

    public void configure(Configuration configuration) throws ConfigurationException {
        libraryManager.configure(configuration.getChild("libraries"));
        widgetDefinitionBuilderSelector.configure(configuration.getChild("widgets"));
    }

    public void dispose() {
        if (this.widgetDefinitionBuilderSelector != null) {
            this.widgetDefinitionBuilderSelector.dispose();
            this.widgetDefinitionBuilderSelector = null;
        }
        if(this.libraryManager != null) {
            this.libraryManager.dispose();
            this.libraryManager = null;
        }
        if (this.cacheManager != null) {
            this.manager.release(this.cacheManager);
            this.cacheManager = null;
        }
        this.manager = null;
    }

    //
    // Business Methods
    //

    public Form createForm(String uri) throws Exception {
        SourceResolver resolver = null;
        Source source = null;
        try {
            try {
                resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
                source = resolver.resolveURI(uri);
            } catch (Exception e) {
                throw new FormsException("Could not resolve form definition URI.",
                                         e, new LocationImpl("[FormManager]", uri));
            }
            return createForm(source);
        } finally {
            if (source != null) {
                resolver.release(source);
            }
            if (resolver != null) {
                manager.release(resolver);
            }
        }
    }

    public Form createForm(Source source) throws Exception {
        FormDefinition formDefinition = createFormDefinition(source);
        Form form = (Form) formDefinition.createInstance();
        form.initialize();
        return form;
    }

    public Form createForm(Element formElement) throws Exception {
        Form form = (Form) createFormDefinition(formElement).createInstance();
        form.initialize();
        return form;
    }

    public FormDefinition createFormDefinition(String uri) throws Exception {
        SourceResolver sourceResolver = null;
        Source source = null;
        try {
            try {
                sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
                source = sourceResolver.resolveURI(uri);
            } catch (Exception e) {
                throw new FormsException("Could not resolve form definition.",
                                         e, new LocationImpl("[FormManager]", uri));
            }
            return createFormDefinition(source);
        } finally {
            if (source != null) {
                sourceResolver.release(source);
            }
            if (sourceResolver != null) {
                manager.release(sourceResolver);
            }
        }
    }

    public FormDefinition createFormDefinition(Source source) throws Exception {
        FormDefinition formDefinition = (FormDefinition) this.cacheManager.get(source, PREFIX);
        if (formDefinition != null && formDefinition.getLocalLibrary().dependenciesHaveChanged()) {
            formDefinition = null; // invalidate
        }

        if (formDefinition == null) {
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Building Form: " + source.getURI());
            }

            Document formDocument;
            try {
                InputSource inputSource = new InputSource(source.getInputStream());
                inputSource.setSystemId(source.getURI());
                formDocument = DomHelper.parse(inputSource, this.manager);
            } catch (Exception e) {
                throw new FormsException("Could not parse form definition.",
                                         e, new LocationImpl("[FormManager]", source.getURI()));
            }

            Element formElement = formDocument.getDocumentElement();
            formDefinition = createFormDefinition(formElement);
            this.cacheManager.set(formDefinition, source, PREFIX);
        }
        return formDefinition;
    }

    public FormDefinition createFormDefinition(Element formElement) throws Exception {
        // check that the root element is a fd:form element
        if (!FormsConstants.DEFINITION_NS.equals(formElement.getNamespaceURI()) || !formElement.getLocalName().equals("form")) {
            throw new FormsException("Expected forms definition <fd:form> element.",
                                     DomHelper.getLocationObject(formElement));
        }

        FormDefinitionBuilder builder = (FormDefinitionBuilder) widgetDefinitionBuilderSelector.select("form");
        return (FormDefinition) builder.buildWidgetDefinition(formElement);
    }


    private class FormServiceManager implements ServiceManager {
        final String WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE = WidgetDefinitionBuilder.class.getName() + "Selector";
        final String LIBRARY_MANAGER_ROLE = LibraryManager.ROLE;

        public Object lookup(String name) throws ServiceException {
            if (WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE.equals(name)) {
                return widgetDefinitionBuilderSelector;
            } else if(LIBRARY_MANAGER_ROLE.equals(name)) {
                return libraryManager;
            } else {
                return manager.lookup(name);
            }
        }

        public boolean hasService(String name) {
            if (WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE.equals(name)) {
                return true;
            } else if(LIBRARY_MANAGER_ROLE.equals(name)) {
                return true;
            } else {
                return manager.hasService(name);
            }
        }

        public void release(Object service) {
            if (service != widgetDefinitionBuilderSelector && service != libraryManager) {
                manager.release(service);
            }
        }
    }
}
