/*  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.bean.processor;

import static org.apache.pluto.container.bean.processor.MethodDescription.METH_ACT;
import static org.apache.pluto.container.bean.processor.MethodDescription.METH_EVT;
import static org.apache.pluto.container.bean.processor.MethodDescription.METH_HDR;
import static org.apache.pluto.container.bean.processor.MethodDescription.METH_REN;
import static org.apache.pluto.container.bean.processor.MethodDescription.METH_RES;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.portlet.PortletException;
import javax.portlet.PortletSession;
import javax.portlet.annotations.ActionMethod;
import javax.portlet.annotations.EventMethod;
import javax.portlet.annotations.HeaderMethod;
import javax.portlet.annotations.PortletSerializable;
import javax.portlet.annotations.PortletSessionScoped;
import javax.portlet.annotations.RenderMethod;
import javax.portlet.annotations.RenderStateScoped;
import javax.portlet.annotations.ServeResourceMethod;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Scott
 *
 */
public class PortletAnnotationRecognizer extends AnnotationRecognizer {
   private static final Logger LOG = LoggerFactory.getLogger(PortletAnnotationRecognizer.class);
   
   
   private final static Set<Class<? extends Annotation>> classAnnotations = 
         new HashSet<Class<? extends Annotation>>();
   
   static {
      classAnnotations.add(RenderStateScoped.class);
      classAnnotations.add(PortletSessionScoped.class);
      classAnnotations.add(SessionScoped.class);
      classAnnotations.add(RequestScoped.class);
   }
   
   // Maps the annotation class to a list of method descriptions. A given annotation
   // may support multiple method signatures, each of which has its own method description.
   private final static Map<Class<? extends Annotation>, List<MethodDescription>> descriptions = 
         new HashMap<Class<? extends Annotation>, List<MethodDescription>>();
   
   static {
      
      ArrayList<MethodDescription> list;
      MethodDescription md;
      
      // Add method definitions for action methods
      
      list = new ArrayList<MethodDescription>();
      list.add(METH_ACT);
      descriptions.put(ActionMethod.class, list);
      
      // Add method definitions for event methods
      
      list = new ArrayList<MethodDescription>();
      list.add(METH_EVT);
      descriptions.put(EventMethod.class, list);
      
      // Add method definitions for serve resource
      
      list = new ArrayList<MethodDescription>();
      
      list.add(METH_RES);
      
      md = new MethodDescription(String.class, 
            new Class<?>[] {},  
            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
            MethodType.RESOURCE);
      md.setAllowMultiple(true);
      md.setVariant(SignatureVariant.STRING_VOID);
      list.add(md);
      
      md = new MethodDescription(void.class, 
            new Class<?>[] {},  
            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
            MethodType.RESOURCE);
      md.setAllowMultiple(true);
      md.setVariant(SignatureVariant.VOID_VOID);
      list.add(md);
      
      descriptions.put(ServeResourceMethod.class, list);
      
      // Add method definitions for render
      
      list = new ArrayList<MethodDescription>();
      
      list.add(METH_REN);
      
      md = new MethodDescription(String.class, 
            new Class<?>[] {},  
            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
            MethodType.RENDER);
      md.setAllowMultiple(true);
      md.setVariant(SignatureVariant.STRING_VOID);
      list.add(md);
      
      md = new MethodDescription(void.class, 
            new Class<?>[] {},  
            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
            MethodType.RENDER);
      md.setAllowMultiple(true);
      md.setVariant(SignatureVariant.VOID_VOID);
      list.add(md);

      descriptions.put(RenderMethod.class, list);
      
      // Add method definitions for header methods
      
      list = new ArrayList<MethodDescription>();
      list.add(METH_HDR);
      
      md = new MethodDescription(String.class, 
            new Class<?>[] {},  
            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
            MethodType.HEADER);
      md.setAllowMultiple(true);
      md.setVariant(SignatureVariant.STRING_VOID);
      list.add(md);
      
      md = new MethodDescription(void.class, 
            new Class<?>[] {},  
            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
            MethodType.HEADER);
      md.setAllowMultiple(true);
      md.setVariant(SignatureVariant.VOID_VOID);
      list.add(md);

      descriptions.put(HeaderMethod.class, list);
      
   }

   private final AnnotatedMethodStore ams;
   private final PortletStateScopedConfig stateScopedConfig = new PortletStateScopedConfig();
   private final PortletSessionScopedConfig sessionScopedConfig = new PortletSessionScopedConfig();
   
   /**
    * @param cla
    * @param metha
    */
   public PortletAnnotationRecognizer(AnnotatedMethodStore pms, ConfigSummary summary) {
      super(classAnnotations, descriptions, summary);
      this.ams = pms;
      LOG.trace("Created the PortletAnnotationRecognizer.");
   }

   /**
    * Extracts data from the class annotation and stores it for later use.
    * <p>
    * When reading the PortletConfiguration annotation, data from a later 
    * annotation will override data from a preceding annotation for a given portlet name.
    * <p>
    * 
    */
   @SuppressWarnings("unchecked")
   @Override
   protected AnnotatedType<?> handleClassAnnotation(Annotation anno, AnnotatedType<?> aType) throws InvalidAnnotationException {
      String typeName = aType.getJavaClass().getCanonicalName();
      Class<?> theClass = aType.getJavaClass();
      
      if (anno instanceof RenderStateScoped) {
         
         // Verify the render state scoped class, store the annotation &
         // bean type with the corresponding bean holder.
         
         if (!PortletSerializable.class.isAssignableFrom(theClass)) {
            StringBuilder txt = new StringBuilder(128);
            txt.append("Annotation problem: An @RenderStateScoped bean must implement PortletSerializable. ");
            txt.append("Annotation: ").append(anno.annotationType().getSimpleName());
            txt.append(", Class: ").append(typeName);
            LOG.debug(txt.toString());
            summary.addStateBeanErrorString(theClass, txt.toString());
         } else {
            stateScopedConfig.addAnnotation(theClass, (RenderStateScoped) anno);
         }
         
      }  else if (anno instanceof PortletSessionScoped) {
         
         // Verify the portlet session scoped class, store the annotation &
         // bean type with the corresponding bean holder.
         
         PortletSessionScoped pss = (PortletSessionScoped) anno;
         if ((pss.value() != PortletSession.APPLICATION_SCOPE) && (pss.value() != PortletSession.PORTLET_SCOPE)) {
            StringBuilder txt = new StringBuilder(128);
            txt.append("Annotation problem: A @PortletSessionScoped bean scope must be APPLICATION_SCOPE or PORTLET_SCOPE. ");
            txt.append("Annotation: ").append(anno.annotationType().getSimpleName());
            txt.append(", Scope: ").append(pss.value());
            txt.append(", Class: ").append(typeName);
            LOG.debug(txt.toString());
            summary.addSessionBeanErrorString(theClass, txt.toString());
         } else {
            sessionScopedConfig.addAnnotation(theClass, pss);
         }

      }  else if (anno instanceof RequestScoped) {

         // Wrap the request scoped bean to make it a portlet request scoped bean, add it to 
         // the summary, and return it so it gets processed by CDI

         PortletRequestScopedAnnotatedType at = new PortletRequestScopedAnnotatedType((AnnotatedType<RequestScoped>)aType);
         summary.addReqScopedType(at);
         return at;
         
      }  else if (anno instanceof SessionScoped) {

         // Wrap the session scoped bean to make it a portlet session scoped bean with application
         // scope, add it to the summary, and return it so it gets processed by CDI

         PortletSessionScopedAnnotatedType at = new PortletSessionScopedAnnotatedType((AnnotatedType<SessionScoped>)aType);
         PortletSessionScoped pss = at.getAnnotation(PortletSessionScoped.class);
         sessionScopedConfig.addAnnotation(theClass, pss);
         summary.addAppScopedType(at);
         return at;

      }  else {
         
         // Any other annotation that lands here indicates a programming error
         
         StringBuilder txt = new StringBuilder(128);
         txt.append("Unrecognized class annotation: ")
            .append(anno.annotationType().getSimpleName());
         txt.append(", Class: ").append(typeName);
         LOG.warn(txt.toString());
      }
      return null;
   }

   /**
    * Extracts and stores relevant information from the specified annotation, bean
    * class, and Method.
    *  
    * @param anno
    * @param beanClass
    * @param meth
    */
   @Override
   protected void handleMethod(Annotation anno, Class<?> beanClass, Method meth, MethodDescription desc) {
      ArrayList<String> portletNames = new ArrayList<String>();
      String dispatchId = "";
      
      MethodType type = desc.getType();
      if (anno instanceof RenderMethod) {
         RenderMethod tcc = (RenderMethod) anno;
         portletNames.addAll(Arrays.asList(tcc.portletNames()));
         dispatchId = tcc.portletMode().toUpperCase();
      } else if (anno instanceof HeaderMethod) {
         HeaderMethod tcc = (HeaderMethod) anno;
         portletNames.addAll(Arrays.asList(tcc.portletNames()));
         dispatchId = tcc.portletMode().toUpperCase();
      } else if (anno instanceof ActionMethod) {
         ActionMethod tcc = (ActionMethod) anno;
         portletNames.add(tcc.portletName());
         dispatchId = tcc.actionName();
      } else if (anno instanceof EventMethod) {
         EventMethod tcc = (EventMethod) anno;
         portletNames.add(tcc.portletName());
      } else if (anno instanceof ServeResourceMethod) {
         ServeResourceMethod tcc = (ServeResourceMethod) anno;
         portletNames.addAll(Arrays.asList(tcc.portletNames()));
         dispatchId = tcc.resourceID();
      } else {
         StringBuilder txt = new StringBuilder(128);
         txt.append("Unrecognized method annotation: ")
            .append(anno.annotationType().getSimpleName());
         txt.append(", Method: ").append(meth.getName());
         txt.append(", Class: ").append(beanClass.getCanonicalName());
         LOG.debug(txt.toString());
         
         // Store the error for each portlet name in array 
         for (String n : getDisplayNames(anno)) {
            summary.addErrorString(n, txt.toString());
         }
         return;
      }
      
      
      // some classAnnotations allow arrays of portlet names. To simplify method retrieval, 
      // add to the method store with each of the specified portlet names.
      // The proxied method is present once, but it is referred to by multiple 
      // method identifier aliases.
      
      AnnotatedMethod pm = new AnnotatedMethod(anno, beanClass, meth, desc);
      for (String portletName : portletNames) {

         // The portlet name may not be empty. Note that the annotation itself
         // will prevent the field from being null.

         if (portletName.length() == 0) {
            StringBuilder txt = new StringBuilder(128);
            txt.append("Bad portlet name. Name may not be of length 0.");
            txt.append(" Annotation: ").append(anno.annotationType().getSimpleName());
            txt.append(", Method: ").append(meth.getName());
            txt.append(", Class: ").append(beanClass.getCanonicalName());
            LOG.debug(txt.toString());
            summary.addErrorString(portletName, txt.toString());
            return;
         }

         // Asterisk is ignored if not first and only array element.

         if (portletName.equals("*") && portletNames.size() > 1) {
            StringBuilder txt = new StringBuilder(128);
            txt.append("Wildcard character '*' must be first and only array element. Will be ignored.");
            txt.append(" Annotation: ").append(anno.annotationType().getSimpleName());
            txt.append(", Method: ").append(meth.getName());
            txt.append(", Class: ").append(beanClass.getCanonicalName());
            LOG.debug(txt.toString());
            summary.addErrorString(portletName, txt.toString());
            continue;
         }

         // we've collected the required info, so store the method.

         MethodIdentifier mi = new MethodIdentifier(portletName, dispatchId, type);
         ams.addMethod(mi, pm);
      }
   }

   
   /**
    * To be called by the CDI extension afterDeploymentValidation method to
    * verify that the stored methods are consistent and to create the bean references.
    *  
    * @param bm      BeanManager needed to activate the beans.
    * @throws InvalidAnnotationException  If the deployment is inconsistent or if the
    *                                     beans cannot be instantiated.
    */
   @Override
   protected void activateCustomScopes(BeanManager bm) {
      
      // Activate the custom scoped beans
      stateScopedConfig.activate(bm);
      sessionScopedConfig.activate(bm);
   }

   
   /**
    * To be called by the CDI extension afterDeploymentValidation method to
    * verify that the stored methods are consistent.
    */
   @Override
   protected void activateAnnotatedMethods(BeanManager bm) {
      
      // Verify the portlet names in the proxied method store. It is an error if:
      // 1) There is no method for a given name, but configuration data exists
      
      Set<String> names = ams.getPortletNames();
      names.remove("*");
      for (String name : names) {
         StringBuilder txt = new StringBuilder(128);
         Set<MethodIdentifier> meths = ams.getMethodIDsForPortlet(name);
         if (meths.isEmpty()) {
            txt.append("No methods exist for portlet.");
            txt.append(" Portlet name: ").append(name);
         }
         if (txt.length() > 0) {
            LOG.debug(txt.toString());
            summary.addErrorString(name, txt.toString());
         }
      }
      
      // See if there is a portlet with a wild-card character. If so, then:
      // 1) Create set of names of portlets without errors
      // 2) replicate the method identifiers to cover all other portlet names
      
      Set<MethodIdentifier> mis = ams.getMethodIDsForPortlet("*");
      if (!mis.isEmpty()) {
         names = ams.getPortletNames();
         names.removeAll(summary.getPortletsWithErrors());
         names.remove("*");
         for (MethodIdentifier mi : mis) {
            List<AnnotatedMethod> meths = ams.getMethods(mi);
            for (String name : names) {
               MethodIdentifier newMi = new MethodIdentifier(name, mi.getId(), mi.getType());
               for (AnnotatedMethod meth : meths) {
                  ams.addMethod(newMi, meth);
               }
            }
         }
      }
      
      //TODO: remove ams initialization
      ams.activateMethods(bm);
      
   }

   /**
    * @return the stateScopedConfig
    */
   public PortletStateScopedConfig getStateScopedConfig() {
      return stateScopedConfig;
   }

   /**
    * @return the stateScopedConfig
    */
   public PortletSessionScopedConfig getSessionScopedConfig() {
      return sessionScopedConfig;
   }

}
