/*
 * 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.net.*;
import java.util.List;
import java.util.Map;
import com.sun.ejte.ccl.reporter.*;

/** 
 * Unit test for:
 *
 *  Multi-byte context root with session cookie
 *
 * Multi-byte context root is specified in sun-web.xml.
 */
public class WebTest {

    private static final String TEST_NAME = "multi-byte-context-root-with-cookie";
    private static final String JSESSIONID = "JSESSIONID";

    private static final String EXPECTED_RESPONSE = "abc=def; myid=123@456";

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

    private String host;
    private String port;

    public WebTest(String[] args) {
        host = args[0];
        port = args[1];
    }
    
    public static void main(String[] args) {

        stat.addDescription("Unit test for Multi-Byte Context Root with Session Cookie");
        WebTest webTest = new WebTest(args);

        try {
            String sessionId = webTest.doSetJsp();
            boolean expected = false;

            if (sessionId != null) {
                expected = webTest.doGetJsp(sessionId);
            }
            if (expected) {
                stat.addStatus(TEST_NAME, stat.PASS);
            } else {
                stat.addStatus(TEST_NAME, stat.FAIL);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            stat.addStatus(TEST_NAME, stat.FAIL);
        }

	    stat.printSummary();
    }

    public String doSetJsp() throws Exception {
     
        String sessionId = null;

        URL url = new URL("http://" + host  + ":" + port + "/"
            + "good-%E5%A5%BD-good/set.jsp");
        System.out.println("Connecting to: " + url.toString());

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.connect();
        int responseCode = conn.getResponseCode();

        if (responseCode == 200) {
            Map<String, List<String>> headers = conn.getHeaderFields();
            List<String> cookies = headers.get("Set-Cookie");
            if (cookies == null) {
                cookies = headers.get("Set-cookie");
            }
            System.out.println("Cookies = " + cookies);

            sessionId = getCookieField(cookies, JSESSIONID);
            System.out.println("sessionId = " + sessionId);
        } else {   
            System.err.println("Unexpected return code: " + responseCode);
        }

        return sessionId;
    }

    private boolean doGetJsp(String sessionId) throws Exception {
        boolean expected = false;

        URL url = new URL("http://" + host  + ":" + port + "/"
            + "good-%E5%A5%BD-good/get.jsp");
        System.out.println("Connecting to: " + url.toString());

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //String cookie = sessionId + "; myid=123@456";
        String cookie = "$Version=1; " + sessionId + "; myid=\"123@456\"";
        conn.setRequestProperty("Cookie", cookie); 
        conn.connect();
        int responseCode = conn.getResponseCode();

        if (responseCode == 200) {
            InputStream is = conn.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line = br.readLine();
            System.out.println("Response=" + line);
            if (EXPECTED_RESPONSE.equals(line)) {
                expected = true;
            } else {
                System.err.println("Wrong response. Expected: " + 
                                   EXPECTED_RESPONSE + ", received: " + line);
            }
        } else {   
            System.err.println("Unexpected return code: " + responseCode);
        }

        return expected;
    }

    private String getCookieField(List<String> cookies, String field) {
        String ret = null;

        if (cookies != null) {
            for (String cookie : cookies) {
                if (cookie.startsWith(field)) {
                    int index = 0;
                    int endIndex = cookie.indexOf(';', index);
                    if (endIndex != -1) {
                        ret = cookie.substring(index, endIndex);
                    } else {
                        ret = cookie.substring(index);
                    }
                    ret = ret.trim();
                    break;
                }
            }
        }

        return ret;
    }
}
