/*
 * 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.lang.*;
import java.io.*;
import java.net.*;

import com.sun.ejte.ccl.reporter.*;

/**
 * Bug 6193728: Multibyte value not processed correctly when request is
 * forwarded to another servlet
 */
public class WebTest {
    
    private static int count = 0;
    private static int EXPECTED_COUNT = 2;
    
    static SimpleReporterAdapter stat=
        new SimpleReporterAdapter("appserv-tests");

    public static void main(String args[]) {
        stat.addDescription("i18 multi byte value test");

        String host = args[0];
        String portS = args[1];
        String contextRoot = args[2];

        int port = new Integer(portS).intValue();
        String name;
        
        try {
            run(host, port, contextRoot + "/ServletTest" );
            
            if (count != EXPECTED_COUNT){
                stat.addStatus("multiByteValue POST", stat.FAIL);
            }           
        } catch (Throwable t) {
            stat.addStatus("multiByteValue", stat.FAIL);
        }

        stat.printSummary("web/multiByteValue---> expect 2 PASS");
    }

    private static void run(String host, int port, String contextPath)
         throws Exception {

        /*
         * Send a GET request
         */
        Socket s = new Socket(host, port);
        OutputStream os = s.getOutputStream();
        System.out.println(("GET " + contextPath + "?j_encoding=Shift_JIS" 
                                                            + " HTTP/1.0\n"));
        os.write(("GET " + contextPath + "?j_encoding=Shift_JIS" 
                                                + " HTTP/1.0\n").getBytes());
        os.write("\n".getBytes());
        
        InputStream is = s.getInputStream();
        BufferedReader bis = new BufferedReader(new InputStreamReader(is));
        String line = null;

        int index, lineNum=0;
        while ((line = bis.readLine()) != null) {
            index = line.indexOf("::");
            System.out.println(lineNum + ":  " + line);
            if (index != -1) {
                String status = line.substring(index+2);
                
                if (status.equalsIgnoreCase("PASS")){
                    stat.addStatus("web-multibyteValue GET: " 
                                        + line.substring(0,index), stat.PASS);
                } else {
                    stat.addStatus("web-multibyteValue GET: " 
                                        + line.substring(0,index), stat.FAIL);                       
                }
                count++;
            } 
            lineNum++;
        }

        /*
         * Send a POST request
         */
        // Construct body
        String body = URLEncoder.encode("j_encoding", "UTF-8")
            + "=" + URLEncoder.encode("Shift_JIS", "UTF-8");
    
        // Create a socket to the host
        s = new Socket(host, port);
        os = s.getOutputStream();
    
        // Send header
        BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(
            s.getOutputStream(), "UTF8"));
        wr.write("POST " + contextPath + " HTTP/1.0\r\n");
        wr.write("Content-Length: " + body.length() + "\r\n");
        wr.write("Content-Type: application/x-www-form-urlencoded\r\n");
        wr.write("\r\n");
    
        // Send body
        wr.write(body);
        wr.flush();

        // Read response
        is = s.getInputStream();
        bis = new BufferedReader(new InputStreamReader(is));
        line = null;

        index=lineNum=0;
        while ((line = bis.readLine()) != null) {
            index = line.indexOf("::");
            System.out.println(lineNum + ":  " + line);
            if (index != -1) {
                String status = line.substring(index+2);
                
                if (status.equalsIgnoreCase("PASS")){
                    stat.addStatus("web-multibyteValue POST: " 
                                        + line.substring(0,index), stat.PASS);
                } else {
                    stat.addStatus("web-multibyteValue POST: " 
                                        + line.substring(0,index), stat.FAIL);                       
                }
                count++;
            } 
            lineNum++;
        }
   }
  
}
