/**
 * 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 static com.google.inject.servlet.ManagedServletPipeline.REQUEST_DISPATCHER_REQUEST;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.spi.BindingScopingVisitor;

import junit.framework.TestCase;

import java.io.IOException;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Ensures servlet spec compliance for CGI-style variables and general
 *  path/pattern matching.
 *
 * @author Dhanji R. Prasanna (dhanji@gmail com)
 */
public class ServletDefinitionPathsTest extends TestCase {

  // Data-driven test.
  public final void testServletPathMatching() throws IOException, ServletException {
    servletPath("/index.html", "*.html", "/index.html");
    servletPath("/somewhere/index.html", "*.html", "/somewhere/index.html");
    servletPath("/somewhere/index.html", "/*", "");
    servletPath("/index.html", "/*", "");
    servletPath("/", "/*", "");
    servletPath("//", "/*", "");
    servletPath("/////", "/*", "");
    servletPath("", "/*", "");
    servletPath("/thing/index.html", "/thing/*", "/thing");
    servletPath("/thing/wing/index.html", "/thing/*", "/thing");
  }

  private void servletPath(final String requestPath, String mapping,
      final String expectedServletPath) throws IOException, ServletException {

    Injector injector = createMock(Injector.class);
    Binding binding = createMock(Binding.class);
    HttpServletRequest request = createMock(HttpServletRequest.class);
    HttpServletResponse response = createMock(HttpServletResponse.class);

    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
        .andReturn(true);
    expect(injector.getBinding(Key.get(HttpServlet.class)))
        .andReturn(binding);

    final boolean[] run = new boolean[1];
    //get an instance of this servlet
    expect(injector.getInstance(Key.get(HttpServlet.class)))
        .andReturn(new HttpServlet() {

          @Override
          protected void service(HttpServletRequest servletRequest,
              HttpServletResponse httpServletResponse) throws ServletException, IOException {

            final String path = servletRequest.getServletPath();
            assertEquals(String.format("expected [%s] but was [%s]", expectedServletPath, path),
                expectedServletPath, path);
            run[0] = true;
          }
        });

    expect(request.getServletPath())
        .andReturn(requestPath);

    replay(injector, binding, request);

    ServletDefinition servletDefinition = new ServletDefinition(mapping, Key.get(HttpServlet.class),
        UriPatternType.get(UriPatternType.SERVLET, mapping), new HashMap<String, String>(), null);

    servletDefinition.init(null, injector,
        Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap()));
    servletDefinition.doService(request, response);

    assertTrue("Servlet did not run!", run[0]);
    
    verify(injector, binding, request);

  }

  // Data-driven test.
  public final void testPathInfoWithServletStyleMatching() throws IOException, ServletException {
    pathInfoWithServletStyleMatching("/path/index.html", "/path", "/*", "/index.html", "");
    pathInfoWithServletStyleMatching("/path//hulaboo///index.html", "/path", "/*",
        "/hulaboo/index.html", "");
    pathInfoWithServletStyleMatching("/path/", "/path", "/*", "/", "");
    pathInfoWithServletStyleMatching("/path////////", "/path", "/*", "/", "");

    // a servlet mapping of /thing/*
    pathInfoWithServletStyleMatching("/path/thing////////", "/path", "/thing/*", "/", "/thing");
    pathInfoWithServletStyleMatching("/path/thing/stuff", "/path", "/thing/*", "/stuff", "/thing");
    pathInfoWithServletStyleMatching("/path/thing/stuff.html", "/path", "/thing/*", "/stuff.html",
        "/thing");
    pathInfoWithServletStyleMatching("/path/thing", "/path", "/thing/*", null, "/thing");

    // see external issue 372
    pathInfoWithServletStyleMatching("/path/some/path/of.jsp", "/path", "/thing/*",
        null, "/some/path/of.jsp");

    // *.xx style mapping
    pathInfoWithServletStyleMatching("/path/thing.thing", "/path", "*.thing", null, "/thing.thing");
    pathInfoWithServletStyleMatching("/path///h.thing", "/path", "*.thing", null, "/h.thing");
    pathInfoWithServletStyleMatching("/path///...//h.thing", "/path", "*.thing", null,
        "/.../h.thing");
    pathInfoWithServletStyleMatching("/path/my/h.thing", "/path", "*.thing", null, "/my/h.thing");

  }

  private void pathInfoWithServletStyleMatching(final String requestUri, final String contextPath,
      String mapping, final String expectedPathInfo, final String servletPath)
      throws IOException, ServletException {

    Injector injector = createMock(Injector.class);
    Binding binding = createMock(Binding.class);
    HttpServletRequest request = createMock(HttpServletRequest.class);
    HttpServletResponse response = createMock(HttpServletResponse.class);

    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
        .andReturn(true);
    expect(injector.getBinding(Key.get(HttpServlet.class)))
        .andReturn(binding);

    final boolean[] run = new boolean[1];
    //get an instance of this servlet
    expect(injector.getInstance(Key.get(HttpServlet.class)))
        .andReturn(new HttpServlet() {

          @Override
          protected void service(HttpServletRequest servletRequest,
              HttpServletResponse httpServletResponse) throws ServletException, IOException {

            final String path = servletRequest.getPathInfo();

            if (null == expectedPathInfo) {
              assertNull(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
                  path);
            }
            else {
              assertEquals(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
                  expectedPathInfo, path);
            }

            //assert memoizer
            //noinspection StringEquality
            assertSame("memo field did not work", path, servletRequest.getPathInfo());

            run[0] = true;
          }
        });

    expect(request.getRequestURI())
        .andReturn(requestUri);

    expect(request.getServletPath())
        .andReturn(servletPath)
        .anyTimes();

    expect(request.getContextPath())
        .andReturn(contextPath);

    expect(request.getAttribute(REQUEST_DISPATCHER_REQUEST)).andReturn(null);

    replay(injector, binding, request);

    ServletDefinition servletDefinition = new ServletDefinition(mapping, Key.get(HttpServlet.class),
        UriPatternType.get(UriPatternType.SERVLET, mapping), new HashMap<String, String>(), null);

    servletDefinition.init(null, injector,
        Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap()));
    servletDefinition.doService(request, response);

    assertTrue("Servlet did not run!", run[0]);

    verify(injector, binding, request);
  }

  // Data-driven test.
  public final void testPathInfoWithRegexMatching() throws IOException, ServletException {
    // first a mapping of /*
    pathInfoWithRegexMatching("/path/index.html", "/path", "/(.)*", "/index.html", "");
    pathInfoWithRegexMatching("/path//hulaboo///index.html", "/path", "/(.)*",
        "/hulaboo/index.html", "");
    pathInfoWithRegexMatching("/path/", "/path", "/(.)*", "/", "");
    pathInfoWithRegexMatching("/path////////", "/path", "/(.)*", "/", "");

    // a servlet mapping of /thing/*
    pathInfoWithRegexMatching("/path/thing////////", "/path", "/thing/(.)*", "/", "/thing");
    pathInfoWithRegexMatching("/path/thing/stuff", "/path", "/thing/(.)*", "/stuff", "/thing");
    pathInfoWithRegexMatching("/path/thing/stuff.html", "/path", "/thing/(.)*", "/stuff.html",
        "/thing");
    pathInfoWithRegexMatching("/path/thing", "/path", "/thing/(.)*", null, "/thing");

    // *.xx style mapping
    pathInfoWithRegexMatching("/path/thing.thing", "/path", ".*\\.thing", null, "/thing.thing");
    pathInfoWithRegexMatching("/path///h.thing", "/path", ".*\\.thing", null, "/h.thing");
    pathInfoWithRegexMatching("/path///...//h.thing", "/path", ".*\\.thing", null,
        "/.../h.thing");
    pathInfoWithRegexMatching("/path/my/h.thing", "/path", ".*\\.thing", null, "/my/h.thing");

    // path
    pathInfoWithRegexMatching("/path/test.com/com.test.MyServletModule", "", "/path/[^/]+/(.*)",
        "com.test.MyServletModule", "/path/test.com/com.test.MyServletModule");
  }

  public final void pathInfoWithRegexMatching(final String requestUri, final String contextPath,
      String mapping, final String expectedPathInfo, final String servletPath)
      throws IOException, ServletException {

    Injector injector = createMock(Injector.class);
    Binding binding = createMock(Binding.class);
    HttpServletRequest request = createMock(HttpServletRequest.class);
    HttpServletResponse response = createMock(HttpServletResponse.class);

    expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
        .andReturn(true);
    expect(injector.getBinding(Key.get(HttpServlet.class)))
        .andReturn(binding);

    final boolean[] run = new boolean[1];
    //get an instance of this servlet
    expect(injector.getInstance(Key.get(HttpServlet.class)))
        .andReturn(new HttpServlet() {

          @Override
          protected void service(HttpServletRequest servletRequest,
              HttpServletResponse httpServletResponse) throws ServletException, IOException {

            final String path = servletRequest.getPathInfo();

            if (null == expectedPathInfo) {
              assertNull(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
                  path);
            }
            else {
              assertEquals(String.format("expected [%s] but was [%s]", expectedPathInfo, path),
                  expectedPathInfo, path);
            }

            //assert memoizer
            //noinspection StringEquality
            assertSame("memo field did not work", path, servletRequest.getPathInfo());

            run[0] = true;
          }
        });

    expect(request.getRequestURI())
        .andReturn(requestUri);

    expect(request.getServletPath())
        .andReturn(servletPath)
        .anyTimes();

    expect(request.getContextPath())
        .andReturn(contextPath);

    expect(request.getAttribute(REQUEST_DISPATCHER_REQUEST)).andReturn(null);

    replay(injector, binding, request);

    ServletDefinition servletDefinition = new ServletDefinition(mapping, Key.get(HttpServlet.class),
        UriPatternType.get(UriPatternType.REGEX, mapping), new HashMap<String, String>(), null);

    servletDefinition.init(null, injector,
        Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap()));
    servletDefinition.doService(request, response);

    assertTrue("Servlet did not run!", run[0]);
    
    verify(injector, binding, request);
  }
}
