/*
 * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

import java.io.*;
import java.net.*;

import com.sun.ejte.ccl.reporter.*;
import org.glassfish.grizzly.test.http2.*;

/*
 * Unit test for deny-uncovered-http-methods.
 */
public class WebTest {

    private static final String TEST_NAME = "servlet-4.0-mapping-discovery";

    private static SimpleReporterAdapter stat
        = new SimpleReporterAdapter("appserv-tests");

    private String host;
    private int port;
    private String contextRoot;
    private String appName;
    private String serverLog;

    public WebTest(String[] args) {
        host = args[0];
        port = Integer.parseInt(args[1]);
        contextRoot = args[2];
        appName = args[3];
        serverLog = args[4];
        
    }
    
    public static void main(String[] args) {

        stat.addDescription("Unit test for mapping discovery");
        WebTest webTest = new WebTest(args);

        try {
            boolean contextRootMatch = webTest.run("GET", 200, false, "/", ".*ServletC.MappingImpl\\{matchValue=.*pattern=/.*servletName=.*,.*mappingMatch=CONTEXT_ROOT\\}.*FORWARD_MAPPING: null.*INCLUDE_MAPPING: null.*ASYNC_MAPPING: null.*");
            boolean defaultMatch = webTest.run("GET", 200, false, "//foo", ".*ServletC.MappingImpl\\{matchValue=.*pattern=/,.*servletName=ServletC.*mappingMatch=DEFAULT\\}.*FORWARD_MAPPING: null.*INCLUDE_MAPPING: null.*ASYNC_MAPPING: null.*");
            boolean exactMatch = webTest.run("GET", 200, false, "/ServletC", ".*ServletC.MappingImpl\\{matchValue=ServletC.*pattern=/ServletC.*servletName=ServletC.*mappingMatch=EXACT\\}.*FORWARD_MAPPING: null.*INCLUDE_MAPPING: null.*ASYNC_MAPPING: null.*");
            boolean extensionMatch = webTest.run("GET", 200, false, "/foo.Issue73", ".*ServletC.MappingImpl\\{matchValue=foo.*pattern=\\*\\.Issue73.*servletName=ServletC.*mappingMatch=EXTENSION\\}.*FORWARD_MAPPING: null.*INCLUDE_MAPPING: null.*ASYNC_MAPPING: null.*");
            boolean pathMatch = webTest.run("GET", 200, false, "/path/foo", ".*ServletC.MappingImpl\\{matchValue=foo.*pattern=/path/\\*.*servletName=ServletC.*mappingMatch=PATH\\}.*FORWARD_MAPPING: null.*INCLUDE_MAPPING: null.*ASYNC_MAPPING: null.*");

            stat.addStatus(TEST_NAME + "-simple", ((contextRootMatch && 
                    defaultMatch &&
                    exactMatch && 
                    extensionMatch &&
                    pathMatch)? stat.PASS : stat.FAIL));
            
            boolean asyncMatch1 = webTest.run("GET", 200, false, "/AAsyncDispatchToC", ".*ServletC.MappingImpl\\{matchValue=AAsyncDispatchToC.*pattern=/AAsyncDispatchToC.*servletName=AAsyncDispatchToC,.*mappingMatch=EXACT\\}.*FORWARD_MAPPING: null.*INCLUDE_MAPPING: null.*ASYNC_MAPPING:.*MappingImpl\\{matchValue=AAsyncDispatchToC.*pattern=/AAsyncDispatchToC.*servletName=AAsyncDispatchToC.*mappingMatch=EXACT}.*");

            boolean asyncMatch2 = webTest.run("GET", 200, false, "/BIncludeDispatchServletNamedDispatcher", ".*In.ServletC.MappingImpl\\{matchValue=BIncludeDispatchServletNamedDispatcher,.pattern=/BIncludeDispatchServletNamedDispatcher,.servletName=BIncludeDispatchServletNamedDispatcher,.mappingMatch=EXACT\\}.*FORWARD_MAPPING:.null.*INCLUDE_MAPPING:.null.*ASYNC_MAPPING:.MappingImpl\\{matchValue=BIncludeDispatchServletNamedDispatcher,.pattern=/BIncludeDispatchServletNamedDispatcher,.servletName=BIncludeDispatchServletNamedDispatcher,.mappingMatch=EXACT\\}.*");

            stat.addStatus(TEST_NAME + "-async",
                           asyncMatch1 &&
                           asyncMatch2 ? stat.PASS : stat.FAIL);
            
            boolean forwardMatch1 = webTest.run("GET", 200, false, "/AForwardToB", ".*ServletC.MappingImpl\\{matchValue=ServletC,.*pattern=/ServletC,.*servletName=ServletC,.*mappingMatch=EXACT\\}.*FORWARD_MAPPING:.MappingImpl\\{matchValue=AForwardToB,.pattern=/AForwardToB,.servletName=AForwardToB,.mappingMatch=EXACT\\}.*INCLUDE_MAPPING:.null.*ASYNC_MAPPING:.null.*");
            boolean forwardMatch2 = webTest.run("GET", 200, false, "/BForwardToC", ".*ServletC.MappingImpl\\{matchValue=ServletC,.*pattern=/ServletC,.*servletName=ServletC,.*mappingMatch=EXACT\\}.*FORWARD_MAPPING:.MappingImpl\\{matchValue=BForwardToC,.pattern=/BForwardToC,.servletName=BForwardToC,.mappingMatch=EXACT\\}.*INCLUDE_MAPPING:.null.*ASYNC_MAPPING:.null.*");

            stat.addStatus(TEST_NAME + "-forward", ((forwardMatch1 &&
                    forwardMatch2)? stat.PASS : stat.FAIL));
            
            boolean includeMatch1 = webTest.run("GET", 200, false, "/AIncludesB", ".*AIncludesB.MappingImpl\\{matchValue=AIncludesB,.pattern=/AIncludesB,.servletName=AIncludesB,.mappingMatch=EXACT\\}.*FORWARD_MAPPING:.null.*INCLUDE_MAPPING:.null.*In.BIncludesC.MappingImpl\\{matchValue=AIncludesB,.pattern=/AIncludesB,.servletName=AIncludesB,.mappingMatch=EXACT\\}.*FORWARD_MAPPING:.null.*INCLUDE_MAPPING:.MappingImpl\\{matchValue=BIncludesC,.pattern=/BIncludesC,.servletName=BIncludesC,.mappingMatch=EXACT\\}.*In.ServletC.MappingImpl\\{matchValue=AIncludesB,.pattern=/AIncludesB,.servletName=AIncludesB,.mappingMatch=EXACT\\}.*FORWARD_MAPPING:.null.*INCLUDE_MAPPING:.MappingImpl\\{matchValue=ServletC,.pattern=/ServletC,.servletName=ServletC,.mappingMatch=EXACT\\}.*ASYNC_MAPPING:.null.*");
            boolean includeMatch2 = webTest.run("GET", 200, false, "/BIncludesC", ".*In.BIncludesC.MappingImpl\\{matchValue=BIncludesC,.pattern=/BIncludesC,.servletName=BIncludesC,.mappingMatch=EXACT\\}.*.FORWARD_MAPPING:.null.*.INCLUDE_MAPPING:.null.*In.ServletC.MappingImpl\\{matchValue=BIncludesC,.pattern=/BIncludesC,.servletName=BIncludesC,.mappingMatch=EXACT\\}.*.FORWARD_MAPPING:.null.*.INCLUDE_MAPPING:.MappingImpl\\{matchValue=ServletC,.pattern=/ServletC,.servletName=ServletC,.mappingMatch=EXACT\\}.*.ASYNC_MAPPING:.null.*");
            stat.addStatus(TEST_NAME + "-include", ((includeMatch1 &&
                    includeMatch2)? stat.PASS : stat.FAIL));
            
            boolean boundsMatch1 = webTest.run("GET", 200, false, "/a/foo", ".*");
            boolean boundsMatch2 = webTest.run("GET", 200, false, "/f", ".*");
            stat.addStatus(TEST_NAME + "-bounds", ((boundsMatch1 && boundsMatch2)? stat.PASS : stat.FAIL));


            boolean namedDispatchMatch1 = webTest.run("GET", 200, false, "/BForwardToCNamedDispatcher", "..*In.ServletC.MappingImpl\\{matchValue=BForwardToCNamedDispatcher,.pattern=/BForwardToCNamedDispatcher,.servletName=BForwardToCNamedDispatcher,.mappingMatch=EXACT\\}</p><p>.FORWARD_MAPPING:.null</p><p>.INCLUDE_MAPPING:.null</p><p>.ASYNC_MAPPING:.null.*");
            boolean namedDispatchMatch2 = webTest.run("GET", 200, false, "/BIncludeCNamedDispatcher", ".*In.ServletC.MappingImpl\\{matchValue=BIncludeCNamedDispatcher,.pattern=/BIncludeCNamedDispatcher,.servletName=BIncludeCNamedDispatcher,.mappingMatch=EXACT\\}</p><p>.FORWARD_MAPPING:.null</p><p>.INCLUDE_MAPPING:.null</p><p>.ASYNC_MAPPING:.null.*");

            stat.addStatus(TEST_NAME + "-namedDispatch", ((namedDispatchMatch1 && namedDispatchMatch2)? stat.PASS : stat.FAIL));
            
            
        } catch( Exception ex) {
            ex.printStackTrace();
            stat.addStatus(TEST_NAME, stat.FAIL);
        }

    	stat.printSummary();
    }

    private boolean run(String method,
            int status, boolean checkOKStatusOnly, String path, String matchRegex) throws Exception {
        System.out.println("host: " + host + " port: " + port + " path: " + path);
        try (HttpClient httpClient = HttpClient.builder().
                host(host).port(port).build()) {
            httpClient.request().path(path).method(method).build().send();
            HttpResponse httpResponse = httpClient.getHttpResponse();
            
            int code = httpResponse.getStatus();
            boolean ok = (code == status);
            if (checkOKStatusOnly) {
                return ok;
            }
            BufferedReader bis = null;
            String line = null;
            
            try {
                bis = new BufferedReader(new StringReader(httpResponse.getBody()));
                line = bis.readLine();
                System.out.println(line);
                ok = line.matches(matchRegex);
                System.out.println("matches: " + ok);
            } catch( Exception ex){
                ex.printStackTrace();   
                throw new Exception("Test UNPREDICTED-FAILURE");
            } finally {
                try {
                    if (bis != null) {
                        bis.close();
                    }
                } catch(IOException ioe) {
                    // ignore
                }
            }
            
            return ok;
        }
    }
    
}
