/**
 * Copyright (C) 2008 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.Binding;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * Central routing/dispatch class handles lifecycle of managed filters, and delegates to the servlet
 * pipeline.
 *
 * @author dhanji@gmail.com (Dhanji R. Prasanna)
 */
@Singleton
class ManagedFilterPipeline implements FilterPipeline{
  private final FilterDefinition[] filterDefinitions;
  private final ManagedServletPipeline servletPipeline;
  private final Provider<ServletContext> servletContext;

  //Unfortunately, we need the injector itself in order to create filters + servlets
  private final Injector injector;

  //Guards a DCL, so needs to be volatile
  private volatile boolean initialized = false;
  private static final TypeLiteral<FilterDefinition> FILTER_DEFS =
      TypeLiteral.get(FilterDefinition.class);

  @Inject
  public ManagedFilterPipeline(Injector injector, ManagedServletPipeline servletPipeline,
      Provider<ServletContext> servletContext) {
    this.injector = injector;
    this.servletPipeline = servletPipeline;
    this.servletContext = servletContext;

    this.filterDefinitions = collectFilterDefinitions(injector);
  }

  /**
   * Introspects the injector and collects all instances of bound {@code List<FilterDefinition>}
   * into a master list.
   * 
   * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
   * that preserves insertion order in entry-set iterators.
   */
  private FilterDefinition[] collectFilterDefinitions(Injector injector) {
    List<FilterDefinition> filterDefinitions = Lists.newArrayList();
    for (Binding<FilterDefinition> entry : injector.findBindingsByType(FILTER_DEFS)) {
      filterDefinitions.add(entry.getProvider().get());
    }

    // Convert to a fixed size array for speed.
    return filterDefinitions.toArray(new FilterDefinition[filterDefinitions.size()]);
  }

  public synchronized void initPipeline(ServletContext servletContext)
      throws ServletException {

    //double-checked lock, prevents duplicate initialization
    if (initialized)
      return;

    // Used to prevent duplicate initialization.
    Set<Filter> initializedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());

    for (FilterDefinition filterDefinition : filterDefinitions) {
      filterDefinition.init(servletContext, injector, initializedSoFar);
    }

    //next, initialize servlets...
    servletPipeline.init(servletContext, injector);

    //everything was ok...
    initialized = true;
  }

  public void dispatch(ServletRequest request, ServletResponse response,
      FilterChain proceedingFilterChain) throws IOException, ServletException {

    //lazy init of filter pipeline (OK by the servlet specification). This is needed
    //in order for us not to force users to create a GuiceServletContextListener subclass.
    if (!initialized) {
      initPipeline(servletContext.get());
    }

    //obtain the servlet pipeline to dispatch against
    new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
        .doFilter(withDispatcher(request, servletPipeline), response);

  }

  /**
   * Used to create an proxy that dispatches either to the guice-servlet pipeline or the regular
   * pipeline based on uri-path match. This proxy also provides minimal forwarding support.
   *
   * We cannot forward from a web.xml Servlet/JSP to a guice-servlet (because the filter pipeline
   * is not called again). However, we can wrap requests with our own dispatcher to forward the
   * *other* way. web.xml Servlets/JSPs can forward to themselves as per normal.
   *
   * This is not a problem cuz we intend for people to migrate from web.xml to guice-servlet,
   * incrementally, but not the other way around (which, we should actively discourage).
   */
  @SuppressWarnings({ "JavaDoc", "deprecation" })
  private ServletRequest withDispatcher(ServletRequest servletRequest,
      final ManagedServletPipeline servletPipeline) {

    HttpServletRequest request = (HttpServletRequest) servletRequest;

    // don't wrap the request if there are no servlets mapped. This prevents us from inserting our
    // wrapper unless it's actually going to be used. This is necessary for compatibility for apps
    // that downcast their HttpServletRequests to a concrete implementation.
    if (!servletPipeline.hasServletsMapped()) {
      return servletRequest;
    }

    //noinspection OverlyComplexAnonymousInnerClass
    return new HttpServletRequestWrapper(request) {

      @Override
      public RequestDispatcher getRequestDispatcher(String path) {
        final RequestDispatcher dispatcher = servletPipeline.getRequestDispatcher(path);

        return (null != dispatcher) ? dispatcher : super.getRequestDispatcher(path);
      }
    };
  }

  public void destroyPipeline() {
    //destroy servlets first
    servletPipeline.destroy();

    //go down chain and destroy all our filters
    Set<Filter> destroyedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
    for (FilterDefinition filterDefinition : filterDefinitions) {
      filterDefinition.destroy(destroyedSoFar);
    }
  }
}
