/*  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.pluto.container.om.portlet.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

import javax.enterprise.inject.spi.BeanManager;
import javax.portlet.annotations.PortletApplication;
import javax.portlet.annotations.PortletConfiguration;
import javax.portlet.annotations.PortletConfigurations;
import javax.portlet.annotations.PortletListener;
import javax.portlet.annotations.PortletPreferencesValidator;
import javax.portlet.annotations.PortletLifecycleFilter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
import org.apache.pluto.container.om.portlet.PortletDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class processes the web app deployment descriptor and the portlet deployment descriptor files.
 * 
 * 
 * @author Scott Nicklous
 * 
 */
public class ConfigurationHolder {

   public static final String           ATTRIB_NAME  = "PortletAppConfig";
   private PortletApplicationDefinition pad          = null;
   private ConfigurationProcessor       jcp          = null;

   /** Logger. */
   private static final Logger          LOG          = LoggerFactory.getLogger(ConfigurationHolder.class);
   private static final boolean         isDebug      = LOG.isDebugEnabled();

   private static final String          JAXB_CONTEXT = "org.apache.pluto.container.om.portlet10.impl:"
                                                           + "org.apache.pluto.container.om.portlet20.impl:"
                                                           + "org.apache.pluto.container.om.portlet30.impl";

   private AnnotatedMethodStore methodStore;
   private boolean portletsInstantiated = false;
   
   /**
    * Default constructor
    */
   public ConfigurationHolder() {
      this.pad = new PortletApplicationDefinitionImpl();
   }

   /**
    * Constructor taking existing portlet app definition - for testing purposes
    * @param pad
    */
   public ConfigurationHolder(PortletApplicationDefinition pad) {
      this.pad = pad;
   }

   /**
    * returns the finished portlet application definition
    * 
    * @return the portlet application definition
    */
   public PortletApplicationDefinition getPad() {
      return pad;
   }

   /**
    * @return the methodStore
    */
   public AnnotatedMethodStore getMethodStore() {
      return methodStore;
   }

   /**
    * @param methodStore the methodStore to set
    */
   public void setMethodStore(AnnotatedMethodStore methodStore) {
      this.methodStore = methodStore;
   }

   /**
    * Processes the portlet deployment descriptor represented by the given input stream.
    * <p>
    * The data is merged into an existing configuration data structure if one is provided. This capability is used by
    * version 3 portlets for merging config data from the files into config data that has been read from annotations.
    * <p>
    * If no existing configuration data is provides, or if a version 1.0 or version 2.0 deployment descriptor is being
    * processed, a new configuration data structure is created.
    * <p>
    * The class also performs validity checking and throws exceptions for invalid data. To maintain compatibility with
    * the earlier Pluto implementation, an <code>IllegalArgumentException</code> is thrown in such cases.
    * 
    * 
    * @param stream
    *           Input stream pointing to deployment descriptor
    * @return The resulting portlet application definition
    * @throws IOException
    *            If an I/O error occurs
    * @throws IllegalArgumentException
    *            If data validation fails
    * @throws XMLStreamException
    */
   public void processPortletDD(InputStream stream) throws IOException, IllegalArgumentException, JAXBException,
         XMLStreamException {

      ClassLoader mycl = this.getClass().getClassLoader();
      JAXBContext cntxt = JAXBContext.newInstance(JAXB_CONTEXT, mycl);

      Unmarshaller um = cntxt.createUnmarshaller();
      XMLInputFactory xif = XMLInputFactory.newFactory();
      XMLStreamReader xsr = xif.createXMLStreamReader(stream);
      JAXBElement<?> jel = (JAXBElement<?>) um.unmarshal(xsr);

      if (jel == null) {
         String warning = "Nothing could be unmarshalled. Stream didn't produce object";
         LOG.warn(warning);
         throw new IOException(warning);
      }

      if (isDebug) {
         StringBuilder txt = new StringBuilder();
         txt.append("Unmarshalled stream. ===> Object type: ");
         txt.append(jel.getValue().getClass().getCanonicalName());
         LOG.debug(txt.toString());
      }

      if (jel.getValue() instanceof org.apache.pluto.container.om.portlet10.impl.PortletAppType) {

         // Ignore existing config data for 1.0 portlets
         pad = new PortletApplicationDefinitionImpl();
         jcp = new JSR168ConfigurationProcessor(pad);

      } else if (jel.getValue() instanceof org.apache.pluto.container.om.portlet20.impl.PortletAppType) {

         // Ignore existing config data for 2.0 portlets
         pad = new PortletApplicationDefinitionImpl();
         jcp = new JSR286ConfigurationProcessor(pad);

      } else if (jel.getValue() instanceof org.apache.pluto.container.om.portlet30.impl.PortletAppType) {

         // if config processor already present, there were annotations. don't overwrite
         jcp = (jcp == null) ? new JSR362ConfigurationProcessor(pad) : jcp;

      } else {
         String warning = "Unknown application type: " + jel.getValue().getClass().getCanonicalName();
         LOG.warn(warning);
         throw new IOException(warning);
      }

      jcp.process(jel);

      if (isDebug) {
         StringBuilder txt = new StringBuilder(128);
         txt.append("Parsed DD for Portlet app: ").append(pad.getName());
         txt.append(", # portlets: ").append(pad.getPortlets().size());
         txt.append(", names: ");
         String sep = "";
         for (PortletDefinition pd : pad.getPortlets()) {
            txt.append(sep).append(pd.getPortletName());
            sep = ", ";
         }
         LOG.debug(txt.toString());
      }

   }

   /**
    * extracts the locale-encoding mapping from the web deployment descriptor
    * 
    * @param in
    *           Input stream for the web DD
    * @throws Exception
    */
   public void processWebDD(InputStream in) throws Exception {
      if (jcp == null) {
         jcp = new JSR286ConfigurationProcessor(pad);
      }
      jcp.processWebDD(in);
   }

   /**
    * Accepts a list of classes that are annotated with portlet configuration and portlet application configuration
    * annotations. Extracts the config data from the annotations to create a corresponding portlet application
    * definition structure.
    * <p>
    * This method must be called before processing the portlet xml so that the data from the portlet DD may properly
    * override the annotation configuration data.
    * <p>
    * This method is designed to be used within a ServletContainerInitializer onStartup() method. The SCI should be
    * annotated as follows: <code>@HandlesTypes({PortletApplication.class, PortletConfiguration.class, #
    * PortletConfigurations.class, PortletLifecycleFilter.class})</code>
    * 
    * @param classes
    *           List of classes annotated with portlet config annotations
    */
   public void processConfigAnnotations(Set<Class<?>> classes) {
      if (classes != null) {
         jcp = new JSR362ConfigurationProcessor(pad);
         for (Class<?> cls : classes) {
            
            PortletApplication pa = cls.getAnnotation(PortletApplication.class);
            if (pa != null) {
               jcp.processPortletAppAnnotation(pa);
            }
            
            PortletConfiguration pc = cls.getAnnotation(PortletConfiguration.class);
            if (pc != null) {
               jcp.processPortletConfigAnnotation(pc, cls);
            }
            
            PortletConfigurations pcs = cls.getAnnotation(PortletConfigurations.class);
            if (pcs != null) {
               for (PortletConfiguration config : pcs.value()) {
                  jcp.processPortletConfigAnnotation(config, cls);
               }
            }
            
            if (cls.getAnnotation(PortletLifecycleFilter.class) != null) {
               jcp.processPortletFilterAnnotation(cls);
            }
            
            if (cls.getAnnotation(PortletListener.class) != null) {
               jcp.processListenerAnnotation(cls);
            }
            
            if (cls.getAnnotation(PortletPreferencesValidator.class) != null) {
               jcp.processValidatorAnnotation(cls);
            }
            
         }
      }
   }

   /**
    * validates the configuration. To be called after the configuration has been completely read.
    */
   public void validate() {
      if (jcp == null) {
         jcp = new JSR362ConfigurationProcessor(pad);
      }
      jcp.validate();
   }

   /**
    * Reconciles the bean configuration with the config from annotations & portlet DD.
    */
   public void reconcileBeanConfig() {
      if (jcp == null) {
         jcp = new JSR362ConfigurationProcessor(pad);
      }
      jcp.reconcileBeanConfig(methodStore);
   }

   /**
    * Instantiates the portlets with the helpt of the bean manager. If the bean 
    * manager is <code>null</code>, the classes are instantiated the old-fashioned way.
    * 
    * @param bm   the bean manager; may be <code>null</code>
    */
   public void instantiatePortlets(BeanManager bm) {
      
      // This method will be called once for each deployed portlet servlet. However,
      // it's important that the methods only be instantiated once per servlet context 
      // to avoid losing initialization data.
      
      if (!portletsInstantiated) {
         portletsInstantiated = true;
         jcp.instantiatePortlets(methodStore, bm);
      }
   }

   /**
    * Reconciles the bean configuration with the config from annotations & portlet DD.
    */
   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
      if (jcp == null) {
         jcp = new JSR362ConfigurationProcessor(pad);
      }
      jcp.reconcileBeanConfig(ams);
      jcp.instantiatePortlets(ams, ams.getBeanMgr());
   }

}
