/*
 * Copyright (c) 1997, 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.util.Properties;
import java.net.*;
import java.security.KeyStore;
import javax.net.*;
import javax.net.ssl.*;
import com.sun.ejte.ccl.reporter.*;

public class WebTest{


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

    private static int count = 0;
    private static int EXPECTED_COUNT = 3;
    private static boolean firstConnection = true;
    private static String requestedSessionId="";
    private static String requestUri = "" ;
    private static String sessionFalseId = "";

    public static void main(String args[]) throws Exception{
        String host = args[0];
        String port = args[1];
        String contextRoot = args[2];
        String trustStorePath = args[3];

        stat.addDescription("Cookie under SSL");

        try {
            SSLSocketFactory ssf = getSSLSocketFactory(trustStorePath);

            HttpsURLConnection connection = doSSLHandshake(
                            "https://" + host  + ":" + port + "/" + contextRoot
                            + "/ServletTest;jsessionid=01A960C22480CE9F445CDE48DE333F31", ssf);

            parseResponse(connection);

            firstConnection = false;
            connection = doSSLHandshake(
                "https://" + host  + ":" + port + "/" + contextRoot
                + "/ServletTest;jsessionid=" + sessionFalseId, ssf);
            parseResponse(connection);

        } catch (Throwable t) {
            t.printStackTrace();
        } finally {
            if (count != EXPECTED_COUNT){
                stat.addStatus("web-sslCookie", stat.FAIL);
            }
        }


        stat.printSummary("web/sslCookie ---> expect 3 PASS");
    }

    private static SSLSocketFactory getSSLSocketFactory(String trustStorePath)
                    throws Exception {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, getTrustManagers(trustStorePath), null);
        return sc.getSocketFactory();
    }

    private static HttpsURLConnection doSSLHandshake(String urlAddress,
                                                     SSLSocketFactory ssf)
                    throws Exception{

        URL url = new URL(urlAddress);
        HttpsURLConnection.setDefaultSSLSocketFactory(ssf);
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

        connection.setHostnameVerifier(
            new HostnameVerifier() {
                public boolean verify(String rserver, SSLSession sses) {
                    return true;
                }
        });
        connection.setDoOutput(true);
        return connection;
    }

    private static int lineNum = 0;

    private static void parseResponse(HttpsURLConnection connection)
                    throws Exception{

        BufferedReader in = null;

        String line= "";
        int index = 0;
        try {
            in = new BufferedReader(
                new InputStreamReader(connection.getInputStream()));
            while ((line = in.readLine()) != null) {
                index = line.indexOf("::");
                System.out.println(lineNum + ":  " + line);
                if (index != -1) {
                    String status = line.substring(index+2);
                    String context = line.substring(0, index);
                    System.out.println("context: " + context + " status: " + status);
                    if (firstConnection){
                        if ( context.equalsIgnoreCase("getRequestSessionId") )
                            requestedSessionId = status;
                        else if ( context.equalsIgnoreCase("getSession(false).getId")) {
                            sessionFalseId = status;
                        } else if ( context.equalsIgnoreCase("getRequestURI"))
                            requestUri = status;
                    } else {
                        if ( context.equalsIgnoreCase("getRequestSessionId") ) {
                            System.out.println(requestedSessionId + " (1) " + status);
                            if (sessionFalseId.equalsIgnoreCase(status)) {
                                stat.addStatus("web-sslCookie: " + context,
                                               stat.PASS);
                            } else {
                                stat.addStatus("web-sslCookie: getRequestSessionId", stat.FAIL);
                            }
                        } else if ( context.equalsIgnoreCase("getSession(false).getId")){
                            System.out.println(sessionFalseId + " (2) " + status);
                            if (sessionFalseId.equalsIgnoreCase(status)) {
                                stat.addStatus("web-sslCookie: " + context,
                                               stat.PASS);
                            } else {
                                stat.addStatus("web-sslCookie: getSession(false).getId", stat.FAIL);
                            }
                        } else if ( context.equalsIgnoreCase("getRequestURI")) {
                            System.out.println(requestUri + " (3) " + status);
                            if (requestUri.equalsIgnoreCase(status)) {
                                stat.addStatus("web-sslCookie: " + context,
                                               stat.PASS);
                            } else {
                                stat.addStatus("web-sslCookie: getRequestURI", stat.FAIL);
                            }
                        }
                        count++;
                    }
                }
                lineNum++;
            }
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch(IOException ioe) {
                // ignore
            }
        }

        in.close();
    }

    private static TrustManager[] getTrustManagers(String path)
                    throws Exception {

        TrustManager[] tms = null;
        InputStream istream = null;

        try {
            KeyStore trustStore = KeyStore.getInstance("JKS");
            istream = new FileInputStream(path);
            trustStore.load(istream, null);
            istream.close();
            istream = null;
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                    TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(trustStore);
            tms = tmf.getTrustManagers();

        } finally {
            if (istream != null) {
                try {
                    istream.close();
                } catch (IOException ioe) {
                    // Do nothing
                }
            }
        }

        return tms;
    }

}
