/*
 * Copyright (c) 2017, 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
 */

package com.sun.ejte.ccl.webrunner.webtest;

import java.net.*;
import java.util.*;
import java.io.*;
import java.lang.*;
import java.util.logging.*;
import com.sun.ejte.ccl.reporter.*;

/**
 *This class is called from WebTest.
 *
 * @author       Deepa Singh (deepa.singh@sun.com)
 *Company       Sun Microsystems Inc.
 *
 */
public class SendRequest {

    private int nThreads;
    private int id ;
    private byte[] filebuf;
    private String website;
    private String cookie_name;
    private String cookie_value;
    private String cookie_path;
    Logger logger = Logger.getLogger("bank.admin");
    ConsoleHandler ch = new ConsoleHandler();
    private String TEST_SUITE_ID = "WEBCLIENT";

    private static String CRLF="\r\n";

    int status,OK=0;
    int notOK=0;
    int url_size;
    double start,end;
    boolean ifdone=false;
    boolean setCookie=false;
    boolean serverCookieSet=false;
    FileOutputStream errout=null;
    //int port=8000;
    private int m_port=80;
    int port;
    private String m_host=new String("local");
    boolean serverSet=false;
    private static int buffer_size=8192;
    private String ws_root;
    Reporter reporter=null;


    public SendRequest(String ws_root,String testsuite_id)
    {
        this.ws_root=ws_root;
        this.TEST_SUITE_ID=testsuite_id;
        reporter = Reporter.getInstance(ws_root);
    }





    public void setServerProperties(String host,int port) {
        this.m_host=host;
        this.m_port=port;
        serverSet=true;
    }



    /**This is a thread safe method so that multiple session of web application can be generated simulataneosly.
     *It parses the byte array and extract individual requests.Uses MimeHeader class for parsing MIME headers.Handles session management by checking if server has set "Set-Cookie" in it's response header.
     *@param host String host name of the web server where web application is to be run e.g. dsingh.sfbay.sun.com
     *@param filebuf byte[] byte array which contains script file.
     *@return int Status Code of web server response.
     *
     */
    public synchronized int processUrl(byte[] filebuf) {
            int responseCode=0;
            int nRequest=0;
            int code=0;
            reporter.setTestSuite(TEST_SUITE_ID, "J2EE Web Client","This test suite integrates web and ejb");


            try {
                    Socket server=null;
                    InetAddress serverAddress=null;
                    BufferedReader bufferedStream=null;
                    DataOutputStream server_out= null;

                    int pos=0;
                    int retVal=0;
                    double currentstart,currentstop;
                    double temp=0;
                    double time=0;
                    char c;
                    String hostName = new String("");

                    int i=0,j=0;
                    MimeHeader mh;
                    while(i<filebuf.length) {
                            c=(char)filebuf[i];

                            switch(c) {
                                    case '!':

                                            if(filebuf[i+1] =='\n' && filebuf[i+2]=='!') {
                                                    nRequest=nRequest+1;
                                                    String temp1=new String(filebuf,j,i-1-j);
                                                    mh=new MimeHeader(temp1);
                                                    if(setCookie) {
                                                            //Cookie: JSESSIONID=4659B62637AC12324972EA5072064469
                                                            //String full_cookie_value="JSESSIONID="+cookie_value+";Path="+cookie_path;
                                                            //String full_cookie_value="JSESSIONID="+cookie_value;
                                                            String full_cookie_value=cookie_name+"="+cookie_value;
                                                            full_cookie_value=full_cookie_value.trim();
                                                            String oldcookie=mh.get("Cookie");
                                                            //  System.out.println("Old Cookie value"+oldcookie);
                                                            mh.put("Cookie",full_cookie_value);
                                                    }

                                                    int stIdx = temp1.indexOf("Host: ");
                                                    stIdx+=5;
                                                    String tp = temp1.substring(stIdx);

                                                    int endIdx = tp.indexOf('\n');
                                                    endIdx+=stIdx;
                                                    hostName = temp1.substring(stIdx, endIdx);

                                                    int portIdx=hostName.indexOf(':');
                                                    String strport=new String();
                                                    if(portIdx > 0){
                                                    strport=hostName.substring(portIdx+1).trim();
                                                            hostName=hostName.substring(0,portIdx);
                                                    //System.out.println("port is"+strport);
}
                                                    hostName = hostName.trim();
                                                    port=new Integer(strport).intValue();
                                                    // if serverSet is true,then use m_host and m_port from the commandline
                                                    //otherwise read host and port from the script.txt
                                                    if(serverSet){
                                                    System.out.println("HTTP port :"+m_port);
                                                    System.out.println("HTTP hostname :"+m_host);
                                                    server=new Socket(m_host,m_port);
                                                    }
                                                    else
                                                        server=new Socket(hostName,port);
                                                    serverAddress=server.getInetAddress();
                                                    bufferedStream=new BufferedReader(new InputStreamReader(server.getInputStream()));
                                                    server_out= new DataOutputStream(server.getOutputStream());
                                                    String req=new String();
                                                    if(mh.ifPOSTRequest()) {
                                                            //System.out.println("POST REQUEST");
                                                            req=mh.getRequestHeader()+ CRLF + mh+CRLF+ mh.getPostData()+CRLF+CRLF;
                                                            //String post="POST" + " " + server_url+ " " + "HTTP/1.0" + CRLF + inmh
                                                            //+ CRLF + postdata+ CRLF+CRLF;

                                                    }
                                                    else
                                                            req=mh.getRequestHeader()+ CRLF + mh + CRLF + CRLF;

                                                    String requestLine=mh.getRequestHeader();
                                                    int fsp=requestLine.indexOf(' ');
                                                    int nsp=requestLine.indexOf(' ',fsp+1);
                                                    int eol=requestLine.indexOf('\n');
                                                    requestLine=requestLine.substring(fsp+1,nsp);

                                                    //Following are debug output statements
                                                    //System.out.println("%%%%%%%%%%%%%%%%%%%%%%Request String Sent to Server%%%%%%%%%%%%%%%%%%%");
                                                    //System.out.println(mh.getRequestHeader());
                                                    //System.out.println(mh);

                                                    try {
                                                            if(server_out!=null)
                                                                    server_out.write(req.getBytes());
                                                            else System.out.println("Server_out is null");
                                                    }
                                                    catch(IOException e) {
                                                            String errMsg=e.getMessage();
                                                            System.out.println(e.getMessage());
                                                    }

                                                    code = readHeader(bufferedStream);
                                                    reporter.addTest(TEST_SUITE_ID,requestLine );
                                                    reporter.addTestCase(TEST_SUITE_ID,requestLine, requestLine );


                                                    if(code==500 || code==404) {
                                                            if(code==404){
                                                                    System.out.println("WebServer returned error code 404");
                                                                    System.out.println("Request Resource not available");
                                                                    System.out.println("There is some deployment error");
                                                            }
                                                            System.out.println("!!Server returned error..Application Exiting");
                                                            reporter.setTestCaseStatus(TEST_SUITE_ID,requestLine,requestLine,ReporterConstants.FAIL);
                                                            //stat.addStatus("WEBCLIENT "+ requestLine,stat.FAIL);
                                                            System.out.println(TEST_SUITE_ID+"\t"+requestLine+"\t FAIL");
                                                            reporter.generateValidReport();
                                                            return 0;
                                                    }
                                                    if (code==200){
                                                            reporter.setTestCaseStatus(TEST_SUITE_ID,requestLine,requestLine,ReporterConstants.PASS);
                                                            //stat.addStatus("WEBCLIENT"+" "+ requestLine,stat.PASS);
                                                            System.out.println(TEST_SUITE_ID+"\t"+requestLine+"\t"+"PASS");
                                                    }

                                            }
                                            i=i+3;
                                            j=i;

                                    default:

                                            i=i+1;
                            }
                            if(time>=temp)
                                    temp=time;

                    }
                    // System.out.println("while loop ended");
                    bufferedStream.close();
                    server_out.close();
                    reporter.generateValidReport();
                    return code;
            }
            catch(Exception e) {
                    e.printStackTrace();
                    String msg=e.getMessage();
            }
            return code;
    }

    public synchronized int readHeader(BufferedReader inStream) {
        int status=0;
        String reasonPhrase = new String("");
        String st=null;
        try {
            StringBuffer result=new StringBuffer();
            st=inStream.readLine();
                /*if(st!=null)
                System.out.println("*****Server Response Starts *****\n"+st );*/

            //st should be of form HTTP/1.1 200 OK
            int fsp=st.indexOf(' ');
            int nsp=st.indexOf(' ',fsp+1);
            int eol=st.indexOf('\n');
            status=Integer.parseInt(st.substring(fsp+1,nsp));
            String line;
            while((line=inStream.readLine())!=null) {

                //Trying to parse
                //Set-Cookie: JSESSIONID=E649A94960EB0304CFA985067EF90893;Path=/bookstore1
                if(line.startsWith("Set-Cookie:") && !setCookie) {
                    if(line!=null) {
                        //   System.out.println("Setting cookie from server");
                        //  System.out.println("COOKIES\t"+line);
                    }

                    int colon=line.indexOf(':');
                    int firstEquals=line.indexOf('=');
                    int semicolon=line.indexOf(';');
                    cookie_name=line.substring(colon+1,firstEquals).trim(); //gives JSESSIONID
                    cookie_value=line.substring(firstEquals+1,semicolon).trim();//gives SessionID
                    cookie_path=line.substring(line.indexOf("Path")+5).trim();
                    setCookie=true;
                }
                if(line!=null) {
                    StringBuffer server_response=new StringBuffer();
                    server_response.append(line);
                    String response=server_response.toString();

                    //System.out.println(line);
                }


            }
            //System.out.println("************Server Response Ends*****************");

        }
        catch(Exception e) {
            System.err.println("-------------------- Read Header Fail---------------------------");
            System.err.println("Error details:" + e.getMessage());
            e.printStackTrace();

            return status;
        }

        return status;
    }

}
