/**
 * Copyright (C) 2006 Google Inc.
 *
 * Licensed 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 com.google.inject.servlet;

import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.internal.Lists;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.http.HttpServlet;

/**
 * Configures the servlet scopes and creates bindings for the servlet API
 * objects so you can inject the request, response, session, etc.
 *
 * <p>
 * You should subclass this module to register servlets and
 * filters in the {@link #configureServlets()} method.
 *
 * @author crazybob@google.com (Bob Lee)
 * @author dhanji@gmail.com (Dhanji R. Prasanna)
 */
public class ServletModule extends AbstractModule {

  @Override
  protected final void configure() {
    // Install common bindings (skipped if already installed).
    install(new InternalServletModule());

    // Install local filter and servlet bindings.
    configureServlets();
    install(filtersModuleBuilder);
    install(servletsModuleBuilder);
  }

  /**
   * <h3>Servlet Mapping EDSL</h3>
   *
   * <p> Part of the EDSL builder language for configuring servlets
   * and filters with guice-servlet. Think of this as an in-code replacement for web.xml.
   * Filters and servlets are configured here using simple java method calls. Here is a typical
   * example of registering a filter when creating your Guice injector:
   *
   * <pre>
   *   Guice.createInjector(..., new ServletModule() {
   *
   *     {@literal @}Override
   *     protected void configureServlets() {
   *       <b>serve("*.html").with(MyServlet.class)</b>
   *     }
   *   }
   * </pre>
   *
   * This registers a servlet (subclass of {@code HttpServlet}) called {@code MyServlet} to service
   * any web pages ending in {@code .html}. You can also use a path-style syntax to register
   * servlets:
   *
   * <pre>
   *       <b>serve("/my/*").with(MyServlet.class)</b>
   * </pre>
   *
   * Every servlet (or filter) is required to be a singleton. If you cannot annotate the class
   * directly, you should add a separate {@code bind(..).in(Singleton.class)} rule elsewhere in
   * your module. Mapping a servlet that is bound under any other scope is an error.
   *
   * <p>
   * <h4>Dispatch Order</h4>
   * You are free to register as many servlets and filters as you like this way. They will
   * be compared and dispatched in the order in which the filter methods are called:
   *
   * <pre>
   *
   *   Guice.createInjector(..., new ServletModule() {
   *
   *     {@literal @}Override
   *     protected void configureServlets() {
   *       filter("/*").through(MyFilter.class);
   *       filter("*.css").through(MyCssFilter.class);
   *       filter("*.jpg").through(new MyJpgFilter());
   *       // etc..
   *
   *       serve("*.html").with(MyServlet.class);
   *       serve("/my/*").with(MyServlet.class);
   *       serve("*.jpg").with(new MyServlet());
   *       // etc..
   *      }
   *    }
   * </pre>
   * This will traverse down the list of rules in lexical order. For example, a url
   *  "{@code /my/file.js}" (after it runs through the matching filters) will first
   *  be compared against the servlet mapping:
   * 
   * <pre>
   *       serve("*.html").with(MyServlet.class);
   * </pre>
   * And failing that, it will descend to the next servlet mapping:
   *
   * <pre>
   *       serve("/my/*").with(MyServlet.class);
   * </pre>
   *
   * Since this rule matches, Guice Servlet will dispatch to {@code MyServlet}. These
   * two mapping rules can also be written in more compact form using varargs syntax:
   *
   * <pre>
   *       serve(<b>"*.html", "/my/*"</b>).with(MyServlet.class);
   * </pre>
   * 
   * This way you can map several URI patterns to the same servlet. A similar syntax is
   * also available for filter mappings.
   *
   * <p>
   * <h4>Regular Expressions</h4>
   * You can also map servlets (or filters) to URIs using regular expressions:
   * <pre>
   *    <b>serveRegex("(.)*ajax(.)*").with(MyAjaxServlet.class)</b>
   * </pre>
   *
   * This will map any URI containing the text "ajax" in it to {@code MyAjaxServlet}. Such as:
   * <ul>
   * <li>http://www.google.com/ajax.html</li>
   * <li>http://www.google.com/content/ajax/index</li>
   * <li>http://www.google.com/it/is_totally_ajaxian</li>
   * </ul>
   *
   *
   * <h3>Initialization Parameters</h3>
   *
   * Servlets (and filters) allow you to pass in init params
   * using the {@code <init-param>} tag in web.xml. You can similarly pass in parameters to
   * Servlets and filters registered in Guice-servlet using a {@link java.util.Map} of parameter
   * name/value pairs. For example, to initialize {@code MyServlet} with two parameters
   * ({@code name="Dhanji", site="google.com"}) you could write:
   *
   * <pre>
   *  Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
   *  params.put("name", "Dhanji");
   *  params.put("site", "google.com");
   *
   *  ...
   *      serve("/*").with(MyServlet.class, <b>params</b>)
   * </pre>
   *
   * <p>
   * <h3>Binding Keys</h3>
   *
   * You can also bind keys rather than classes. This lets you hide
   * implementations with package-local visbility and expose them using
   * only a Guice module and an annotation:
   *
   * <pre>
   *  ...
   *      filter("/*").through(<b>Key.get(Filter.class, Fave.class)</b>);
   * </pre>
   *
   * Where {@code Filter.class} refers to the Servlet API interface and {@code Fave.class} is a
   * custom binding annotation. Elsewhere (in one of your own modules) you can bind this
   * filter's implementation:
   *
   * <pre>
   *   bind(Filter.class)<b>.annotatedWith(Fave.class)</b>.to(MyFilterImpl.class);
   * </pre>
   *
   * See {@link com.google.inject.Binder} for more information on binding syntax.
   *
   * <p>
   * <h3>Multiple Modules</h3>
   *
   * It is sometimes useful to capture servlet and filter mappings from multiple different
   * modules. This is essential if you want to package and offer drop-in Guice plugins that
   * provide servlet functionality.
   *
   * <p>
   * Guice Servlet allows you to register several instances of {@code ServletModule} to your
   * injector. The order in which these modules are installed determines the dispatch order
   * of filters and the precedence order of servlets. For example, if you had two servlet modules,
   * {@code RpcModule} and {@code WebServiceModule} and they each contained a filter that mapped
   * to the same URI pattern, {@code "/*"}:
   *
   * <p>
   * In {@code RpcModule}:
   * <pre>
   *     filter("/*").through(RpcFilter.class);
   * </pre>
   *
   * In {@code WebServiceModule}:
   * <pre>
   *     filter("/*").through(WebServiceFilter.class);
   * </pre>
   *
   * Then the order in which these filters are dispatched is determined by the order in which
   * the modules are installed:
   *
   * <pre>
   *   <b>install(new WebServiceModule());</b>
   *   install(new RpcModule());
   * </pre>
   *
   * In the case shown above {@code WebServiceFilter} will run first.
   * 
   * @since 2.0
   */
  protected void configureServlets() {
  }


  private final FiltersModuleBuilder filtersModuleBuilder = new FiltersModuleBuilder();
  private final ServletsModuleBuilder servletsModuleBuilder = new ServletsModuleBuilder();

  /**
   * @param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
   * @since 2.0
   */
  protected final FilterKeyBindingBuilder filter(String urlPattern, String... morePatterns) {
    return filtersModuleBuilder.filter(Lists.newArrayList(urlPattern, morePatterns));
  }

  /**
   * @param regex Any Java-style regular expression.
   * @since 2.0
   */
  protected final FilterKeyBindingBuilder filterRegex(String regex, String... regexes) {
    return filtersModuleBuilder.filterRegex(Lists.newArrayList(regex, regexes));
  }

  /**
   * @param urlPattern Any Servlet-style pattern. examples: /*, /html/*, *.html, etc.
   * @since 2.0
   */
  protected final ServletKeyBindingBuilder serve(String urlPattern, String... morePatterns) {
    return servletsModuleBuilder.serve(Lists.newArrayList(urlPattern, morePatterns));
  }

  /**
   * @param regex Any Java-style regular expression.
   * @since 2.0
   */
  protected final ServletKeyBindingBuilder serveRegex(String regex, String... regexes) {
    return servletsModuleBuilder.serveRegex(Lists.newArrayList(regex, regexes));
  }

  /**
   * See the EDSL examples at {@link ServletModule#configureServlets()}
   *
   * @since 2.0
   */
  public static interface FilterKeyBindingBuilder {
    void through(Class<? extends Filter> filterKey);
    void through(Key<? extends Filter> filterKey);
    void through(Filter filter);
    void through(Class<? extends Filter> dummyFilterClass, Map<String, String> contextParams);
    void through(Key<? extends Filter> dummyFilterClass, Map<String, String> contextParams);
    void through(Filter filter, Map<String, String> contextParams);
  }

  /**
   * See the EDSL examples at {@link ServletModule#configureServlets()}
   *
   * @since 2.0
   */
  public static interface ServletKeyBindingBuilder {
    void with(Class<? extends HttpServlet> servletKey);
    void with(Key<? extends HttpServlet> servletKey);
    void with(HttpServlet servlet);
    void with(Class<? extends HttpServlet> servletKey, Map<String, String> contextParams);
    void with(Key<? extends HttpServlet> servletKey, Map<String, String> contextParams);
    void with(HttpServlet servlet, Map<String, String> contextParams);
  }
}
