/*
 * 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;
    }
}
