/*
 * Copyright (c) 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.util.*;

/**
 *
* MIME is an internet standard for communicating multimedia content over e-mail systems.MimeHeader extends HashTable so that it can store key value pairs.
 *
* @author       Deepa Singh(deepa.singh@sun.com)
 *Company: Sun Microsystems Inc
 *@see com.sun.ejte.ccl.webrunner.proxy.MimeHeader
* 
*/

public class MimeHeader extends Hashtable
{
    private String RequestHeader=new String();
    private  boolean requestGET=false;
    private boolean requestPOST=false;
    private boolean cookieSet=false;
    private String postdata=new String();
    
    
    /**
     * Takes a String as a parameter and parses it.Takes a raw MIME-formatted String and enter its key/value pairs into a given instance of MimeHeader.Uses
     *StringTokenizer to split the input data into individual lines marked by CRLF(\r\n) sequence.
     *It differs in it's implementation of parse() from com.sun.ejte.ccl.webrunner.proxy.MimeHeader.parse() in that it checks the request type.
     *If it is POST then stores the post data to be sent to external web server.
     * @author       Deepa Singh(deepa.singh@sun.com)
     * @return       void
     * @param		data	The string to be parsed
     **@see com.sun.ejte.ccl.webrunner.proxy.MimeHeader
    */
    void parse(String data)
    {
	StringTokenizer st=new StringTokenizer(data,"\r\n");
	while(st.hasMoreTokens())
	{
            String s=st.nextToken();
            
            //first check for Cookie as they are contained in script file.This needs to be stripped from the new request string sent to server
            if(s.startsWith("Cookie"))
            {
                cookieSet=true;
            }
            else
                cookieSet=false;

            //These lines are HTTP headers.Do not contain request.
            if(!s.startsWith("GET") && (!s.startsWith("POST")))
            {
                //System.out.println("_from_mime_header"+s);
                if((s.indexOf(':'))!=-1)
                {
                    int colon=s.indexOf(':');
                    String key=s.substring(0,colon);
                    String val=s.substring(colon+2);
                    put(key,val);
                }
                //This is POST data after request and headers.Header has ended and after CRLF Content starts.
                //\r\n\r\n is CRLF.Header lines are separated by \r\n
                else
                {
                    //System.out.println("\n%%%%%%POST DATA%%%%%%");
                    postdata=s;
                    postdata.trim();
                    System.out.println(postdata);
                }
            }
            //This is the first line of HTTP request
            else
            {
                RequestHeader=s;
                if((RequestHeader.indexOf("GET"))!=-1)
                    requestGET=true;
                else if((RequestHeader.indexOf("POST"))!=-1)
                    requestPOST=true;
            }
	}
    }

	MimeHeader(){}
        public boolean ifGETRequest()
        {
            return this.requestGET;
        }
        public boolean ifPOSTRequest()
        {
            return this.requestPOST;
        }
        public String getRequestHeader()
        {
            return this.RequestHeader;
        }
	MimeHeader(String d)
	{
		parse(d);
	}

	public String toString()
	{
		String ret="";
		Enumeration e=keys();
		while(e.hasMoreElements())
		{
		String key=(String)e.nextElement();
		String val=(String)get(key);
		ret+=key + ": " + val + "\r\n";
		}
	return ret;
	}
        
        public String getPostData()
        {
                return postdata.trim();
                        
        }
        


	/**
	*To remove the discrepancy in MIME specification for "Content-Type" and "content-type" and "Content-Length" to "content-length"
         *To avoid problems, all incoming and outgoing MimeHeader keys are converted to canonical form. 
	* @author       Deepa Singh(deepa.singh@sun.com)
	* @return       String
	* @param		ms	String to be operated upon
	*/
        private String fix(String ms)
	{
	char chars[]=ms.toLowerCase().toCharArray();
	boolean upcaseNext=true;
	for(int i=0;i<chars.length-1;i++)
	{
		char ch=chars[i];
		if(upcaseNext && 'a' <=ch && ch <='z')
		{
			chars[i]=(char)(ch-('a'-'A'));
		}
		upcaseNext=ch=='-';
	}
	return new String(chars);
	}


	/*
        * @author       Deepa Singh(deepa.singh@sun.com)
       * @return        String
       * @param		String key MIME header e.g Content-Type
        
       **@see com.sun.ejte.ccl.webrunner.proxy.MimeHeader
       */
        public String get(String key)
	{
	return (String)super.get(fix(key));
	}

     
       /*
        * @author       Deepa Singh(deepa.singh@sun.com)
       * @return       void
       * @param		String key MIME header e.g Content-Type
        *@param         String value value of MIME header
       **@see com.sun.ejte.ccl.webrunner.proxy.MimeHeader
       */
        public void put(String key,String val)
	{
	super.put(fix(key),val);
	}
}
