package org.jboss.resteasy.integration.deployers;

import org.jboss.deployers.spi.DeploymentException;
import org.jboss.deployers.spi.deployer.DeploymentStages;
import org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer;
import org.jboss.deployers.structure.spi.DeploymentUnit;
import org.jboss.logging.Logger;
import org.jboss.metadata.javaee.spec.ParamValueMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.metadata.web.spec.FilterMappingMetaData;
import org.jboss.metadata.web.spec.FilterMetaData;
import org.jboss.metadata.web.spec.FiltersMetaData;
import org.jboss.resteasy.plugins.server.servlet.FilterDispatcher;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
 * @version $Revision: 1 $
 */
public class ResteasyIntegrationDeployer extends AbstractRealDeployer
{
   private static final Logger LOGGER = Logger.getLogger(ResteasyIntegrationDeployer.class);

   public ResteasyIntegrationDeployer()
   {
      super();

      addRequiredInput(JBossWebMetaData.class);
      addRequiredInput(ResteasyDeploymentData.class);
      addOutput(JBossWebMetaData.class);
      setStage(DeploymentStages.PRE_REAL); // TODO -- right stage?
   }

   protected void populateWebMetadata()
   {

   }

   protected void setInitParam(FilterMetaData filter, String name, String value)
   {
      ParamValueMetaData param = new ParamValueMetaData();
      param.setParamName(name);
      param.setParamValue(value);
      List<ParamValueMetaData> params = filter.getInitParam();
      if (params == null)
      {
         params = new ArrayList<ParamValueMetaData>();
         filter.setInitParam(params);
      }
      params.add(param);

   }

   protected void internalDeploy(DeploymentUnit du) throws DeploymentException
   {
      JBossWebMetaData webdata = du.getAttachment(JBossWebMetaData.class);
      ResteasyDeploymentData resteasy = du.getAttachment(ResteasyDeploymentData.class);
      if (!resteasy.shouldCreateDispatcher()) return;

      FilterMetaData filter = new FilterMetaData();
      filter.setFilterClass(FilterDispatcher.class.getName());
      filter.setName("Resteasy");

      if (!resteasy.getResources().isEmpty())
      {
         StringBuffer buf = null;
         for (String resource : resteasy.getResources())
         {
            if (buf == null)
            {
               buf = new StringBuffer();
               buf.append(resource);
            }
            else
            {
               buf.append(",").append(resource);
            }
            log.info("******** Adding RESOURCE CLASS: " + resource);
         }
         String resources = buf.toString();
         setInitParam(filter, ResteasyContextParameters.RESTEASY_RESOURCES, resources);
      }
      if (!resteasy.getProviders().isEmpty())
      {
         StringBuffer buf = null;
         for (String provider : resteasy.getProviders())
         {
            if (buf == null)
            {
               buf = new StringBuffer();
               buf.append(provider);
            }
            else
            {
               buf.append(",").append(provider);
            }
         }
         setInitParam(filter, ResteasyContextParameters.RESTEASY_PROVIDERS, buf.toString());
      }
      FilterMappingMetaData mapping = new FilterMappingMetaData();
      mapping.setFilterName("Resteasy");
      List<String> patterns = new ArrayList<String>();
      patterns.add("/*");
      mapping.setUrlPatterns(patterns);

      if (webdata.getFilters() == null)
      {
         webdata.setFilters(new FiltersMetaData());
      }
      webdata.getFilters().add(filter);
      List<FilterMappingMetaData> mappings = webdata.getFilterMappings();
      if (mappings == null)
      {
         mappings = new ArrayList<FilterMappingMetaData>();
         webdata.setFilterMappings(mappings);
      }
      mappings.add(mapping);
   }

}