/*
 * 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 com.sun.ejte.ccl.reporter.*;

/*
 * Unit test for BOM in JSP classic (standard) syntax.
 *
 * Each of the JSP pages accessed by this test is preceded by a BOM from
 * which the JSP container derives the page encoding:
 *
 *  Page           Page Encoding          Bytes
 *  UTF-16BE.jsp   UTF-16, big-endian     FE FF
 *  UTF-16LE.jsp   UTF-16, little-endian  FF FE
 *  UTF-8.jsp      UTF-8                  EF BB BF
 *
 * This test enforces that the BOM does not appear in the generated page
 * output, and that the charset component of the Content-Type response header
 * matches the charset identified by the BOM.
 */
public class WebTest {

    private static final String TEST_NAME = "jsp-bom-in-classic-syntax";

    private static final String TEXT_HTML_UTF_16_BE
        = "text/html;charset=UTF-16BE";
    private static final String TEXT_HTML_UTF_16_LE
        = "text/html;charset=UTF-16LE";
    private static final String TEXT_HTML_UTF_8
        = "text/html;charset=UTF-8";

    private static final String EXPECTED_RESPONSE = "this is a test";

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

    private String host;
    private String port;
    private String contextRoot;

    public WebTest(String[] args) {
        host = args[0];
        port = args[1];
        contextRoot = args[2];
    }

    public static void main(String[] args) {

        stat.addDescription("Unit test for BOM in JSP classic syntax");
        WebTest webTest = new WebTest(args);

        try {
            boolean pass = webTest.doTest("UTF-16BE.jsp");
            if (!pass) {
                stat.addStatus(TEST_NAME, stat.FAIL);
            } else {
                pass = webTest.doTest("UTF-16LE.jsp");
                if (!pass) {
                    stat.addStatus(TEST_NAME, stat.FAIL);
                } else {
                    pass = webTest.doTest("UTF-8.jsp");
                    if (!pass) {
                        stat.addStatus(TEST_NAME, stat.FAIL);
                    } else {
                        stat.addStatus(TEST_NAME, stat.PASS);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            stat.addStatus(TEST_NAME, stat.FAIL);
        }

    stat.printSummary();
    }

    /*
     * @return true if passed, false if failed
     */
    public boolean doTest(String jspPage) throws Exception {

        InputStream is = null;
        BufferedReader input = null;
        try {
            URL url = new URL("http://" + host  + ":" + port
                              + contextRoot + "/" + jspPage);
            System.out.println("Connecting to: " + url.toString());
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.connect();

            int responseCode = conn.getResponseCode();
            if (responseCode != 200) {
                System.err.println("Wrong response code. Expected: 200"
                                   + ", received: " + responseCode);
                return false;
            }

            is = conn.getInputStream();

            String contentType = conn.getHeaderField("Content-Type");
            if ("UTF-16BE.jsp".equals(jspPage)) {
                if (!TEXT_HTML_UTF_16_BE.equals(contentType)) {
                    System.err.println("Wrong response content-type. "
                                       + "Expected: " + TEXT_HTML_UTF_16_BE
                                       + ", received: " + contentType);
                    return false;
                }
            } else if ("UTF-16LE.jsp".equals(jspPage)) {
                if (!TEXT_HTML_UTF_16_LE.equals(contentType)) {
                    System.err.println("Wrong response content-type. "
                                       + "Expected: " + TEXT_HTML_UTF_16_LE
                                       + ", received: " + contentType);
                    return false;
                }
            } else if ("UTF-8.jsp".equals(jspPage)) {
                if (!TEXT_HTML_UTF_8.equals(contentType)) {
                    System.err.println("Wrong response content-type. "
                                       + "Expected: " + TEXT_HTML_UTF_8
                                       + ", received: " + contentType);
                    return false;
                }
            } else {
                return false;
            }

            String charSet = getCharSet(contentType);
            if (charSet == null) {
                return false;
            }

            input = new BufferedReader(
                    new InputStreamReader(is, charSet));
            String line = input.readLine();
            if (!EXPECTED_RESPONSE.equals(line)) {
                System.err.println("Wrong response. "
                                   + "Expected: " + EXPECTED_RESPONSE
                                   + ", received: " + line);
                return false;
            }

            // Success
            return true;
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException ex) {}
            try {
                if (input != null) input.close();
            } catch (IOException ex) {}
        }
    }


    private String getCharSet(String contentType) {

        int index = contentType.indexOf('=');
        if (index < 0) {
            System.err.println("Unable to get charset from content-type");
            return null;
        }

        return contentType.substring(index+1);
    }
}
