/*
 * 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.catalina.mapper;

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

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

import org.junit.Assert;
import org.junit.Test;

import org.apache.catalina.Context;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.catalina.valves.RemoteAddrValve;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.apache.tomcat.websocket.server.WsContextListener;

/**
 * Mapper tests that use real web applications on a running Tomcat.
 */
public class TestMapperWebapps extends TomcatBaseTest{

    @Test
    public void testContextRoot_Bug53339() throws Exception {
        Tomcat tomcat = getTomcatInstance();
        tomcat.enableNaming();

        // No file system docBase required
        Context ctx = tomcat.addContext("", null);

        Tomcat.addServlet(ctx, "Bug53356", new Bug53356Servlet());
        ctx.addServletMappingDecoded("", "Bug53356");

        tomcat.start();

        ByteChunk body = getUrl("http://localhost:" + getPort());

        Assert.assertEquals("OK", body.toString());
    }

    private static class Bug53356Servlet extends HttpServlet {

        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // Confirm behaviour as per Servlet 12.2
            boolean pass = "/".equals(req.getPathInfo());
            if (pass) {
                pass = "".equals(req.getServletPath());
            }
            if (pass) {
                pass = "".equals(req.getContextPath());
            }

            resp.setContentType("text/plain");
            if (pass) {
                resp.getWriter().write("OK");
            } else {
                resp.getWriter().write("FAIL");
            }
        }
    }

    @Test
    public void testContextReload_Bug56658_Bug56882() throws Exception {
        Tomcat tomcat = getTomcatInstance();

        File appDir = new File(getBuildDirectory(), "webapps/examples");
        // app dir is relative to server home
        org.apache.catalina.Context ctxt  = tomcat.addWebapp(
                null, "/examples", appDir.getAbsolutePath());
        ctxt.addApplicationListener(WsContextListener.class.getName());
        tomcat.start();

        // The tests are from TestTomcat#testSingleWebapp(), #testJsps()
        // We reload the context and verify that the pages are still accessible
        ByteChunk res;
        String text;

        res = getUrl("http://localhost:" + getPort()
                + "/examples/servlets/servlet/HelloWorldExample");
        text = res.toString();
        Assert.assertTrue(text, text.contains("<a href=\"../helloworld.html\">"));

        res = getUrl("http://localhost:" + getPort()
                + "/examples/jsp/jsp2/el/basic-arithmetic.jsp");
        text = res.toString();
        Assert.assertTrue(text, text.contains("<td>${(1==2) ? 3 : 4}</td>"));

        res = getUrl("http://localhost:" + getPort() + "/examples/index.html");
        text = res.toString();
        Assert.assertTrue(text, text.contains("<title>Apache Tomcat Examples</title>"));

        long timeA = System.currentTimeMillis();
        res = getUrl("http://localhost:" + getPort()
                + "/examples/jsp/include/include.jsp");
        String timestamp = findCommonPrefix(timeA, System.currentTimeMillis());
        text = res.toString();
        Assert.assertTrue(text, text.contains(
                "In place evaluation of another JSP which gives you the current time: " + timestamp));
        Assert.assertTrue(text, text.contains(
                "To get the current time in ms"));
        Assert.assertTrue(text, text.contains(
                "by including the output of another JSP: " + timestamp));
        Assert.assertTrue(text, text.contains(":-)"));

        res = getUrl("http://localhost:" + getPort()
                + "/examples/jsp/forward/forward.jsp");
        text = res.toString();
        Assert.assertTrue(text, text.contains("VM Memory usage"));

        ctxt.reload();

        res = getUrl("http://localhost:" + getPort()
                + "/examples/servlets/servlet/HelloWorldExample");
        text = res.toString();
        Assert.assertTrue(text, text.contains("<a href=\"../helloworld.html\">"));

        res = getUrl("http://localhost:" + getPort()
                + "/examples/jsp/jsp2/el/basic-arithmetic.jsp");
        text = res.toString();
        Assert.assertTrue(text, text.contains("<td>${(1==2) ? 3 : 4}</td>"));

        res = getUrl("http://localhost:" + getPort() + "/examples/index.html");
        text = res.toString();
        Assert.assertTrue(text, text.contains("<title>Apache Tomcat Examples</title>"));

        timeA = System.currentTimeMillis();
        res = getUrl("http://localhost:" + getPort()
                + "/examples/jsp/include/include.jsp");
        timestamp = findCommonPrefix(timeA, System.currentTimeMillis());
        text = res.toString();
        Assert.assertTrue(text, text.contains(
                "In place evaluation of another JSP which gives you the current time: " + timestamp));
        Assert.assertTrue(text, text.contains(
                "To get the current time in ms"));
        Assert.assertTrue(text, text.contains(
                "by including the output of another JSP: " + timestamp));
        Assert.assertTrue(text, text.contains(":-)"));

        res = getUrl("http://localhost:" + getPort()
                + "/examples/jsp/forward/forward.jsp");
        text = res.toString();
        Assert.assertTrue(text, text.contains("VM Memory usage"));
    }

    @Test
    public void testWelcomeFileNotStrict() throws Exception {

        Tomcat tomcat = getTomcatInstance();

        File appDir = new File("test/webapp");

        StandardContext ctxt = (StandardContext) tomcat.addWebapp(null, "/test",
                appDir.getAbsolutePath());
        ctxt.setReplaceWelcomeFiles(true);
        ctxt.addWelcomeFile("index.jsp");
        // Mapping for *.do is defined in web.xml
        ctxt.addWelcomeFile("index.do");

        tomcat.start();
        ByteChunk bc = new ByteChunk();
        int rc = getUrl("http://localhost:" + getPort() +
                "/test/welcome-files", bc, new HashMap<String,List<String>>());
        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
        Assert.assertTrue(bc.toString().contains("JSP"));

        rc = getUrl("http://localhost:" + getPort() +
                "/test/welcome-files/sub", bc,
                new HashMap<String,List<String>>());
        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
        Assert.assertTrue(bc.toString().contains("Servlet"));
    }

    @Test
    public void testWelcomeFileStrict() throws Exception {

        Tomcat tomcat = getTomcatInstance();

        File appDir = new File("test/webapp");

        StandardContext ctxt = (StandardContext) tomcat.addWebapp(null, "/test",
                appDir.getAbsolutePath());
        ctxt.setReplaceWelcomeFiles(true);
        ctxt.addWelcomeFile("index.jsp");
        // Mapping for *.do is defined in web.xml
        ctxt.addWelcomeFile("index.do");

        // Simulate STRICT_SERVLET_COMPLIANCE
        ctxt.setResourceOnlyServlets("");

        tomcat.start();
        ByteChunk bc = new ByteChunk();
        int rc = getUrl("http://localhost:" + getPort() +
                "/test/welcome-files", bc, new HashMap<String,List<String>>());
        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
        Assert.assertTrue(bc.toString().contains("JSP"));

        rc = getUrl("http://localhost:" + getPort() +
                "/test/welcome-files/sub", bc,
                new HashMap<String,List<String>>());
        Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, rc);
    }

    @Test
    public void testRedirect() throws Exception {
        Tomcat tomcat = getTomcatInstance();

        // Use standard test webapp as ROOT
        File rootDir = new File("test/webapp");
        org.apache.catalina.Context root =
                tomcat.addWebapp(null, "", rootDir.getAbsolutePath());

        // Add a security constraint
        SecurityConstraint constraint = new SecurityConstraint();
        SecurityCollection collection = new SecurityCollection();
        collection.addPatternDecoded("/welcome-files/*");
        collection.addPatternDecoded("/welcome-files");
        constraint.addCollection(collection);
        constraint.addAuthRole("foo");
        root.addConstraint(constraint);

        // Also make examples available
        File examplesDir = new File(getBuildDirectory(), "webapps/examples");
        org.apache.catalina.Context examples  = tomcat.addWebapp(
                null, "/examples", examplesDir.getAbsolutePath());
        examples.setMapperContextRootRedirectEnabled(false);
        // Then block access to the examples to test redirection
        RemoteAddrValve rav = new RemoteAddrValve();
        rav.setDeny(".*");
        rav.setDenyStatus(404);
        examples.getPipeline().addValve(rav);

        tomcat.start();

        // Redirects within a web application
        doRedirectTest("/welcome-files", 401);
        doRedirectTest("/welcome-files/", 401);

        doRedirectTest("/jsp", 302);
        doRedirectTest("/jsp/", 404);

        doRedirectTest("/WEB-INF", 404);
        doRedirectTest("/WEB-INF/", 404);

        // Redirects between web applications
        doRedirectTest("/examples", 404);
        doRedirectTest("/examples/", 404);
    }


    private void doRedirectTest(String path, int expected) throws IOException {
        ByteChunk bc = new ByteChunk();
        int rc = getUrl("http://localhost:" + getPort() + path, bc, false);
        Assert.assertEquals(expected, rc);
    }


    /**
     * Prepare a string to search in messages that contain a timestamp, when it
     * is known that the timestamp was printed between {@code timeA} and
     * {@code timeB}.
     */
    private static String findCommonPrefix(long timeA, long timeB) {
        while ((timeA != timeB) && timeA > 0) {
            timeA /= 10;
            timeB /= 10;
        }
        return String.valueOf(timeA);
    }
}
