//$Id

package com.util;

//import Java
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.io.FileWriter;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.StringReader;
import java.io.InterruptedIOException;
import java.net.URL;
import java.net.URI;
import java.net.UnknownHostException;
//import org.w3c.dom.*;
//import org.xml.sax.*;
//import javax.xml.parsers.*;
import com.sun.net.ssl.X509TrustManager;
import com.sun.net.ssl.TrustManager;
import com.sun.net.ssl.SSLContext;
import javax.security.cert.X509Certificate;

import HTTPClient.*;

/**
 * This class is used in communicating with the Zoho service.
 * Sends the request to Zoho service and receives the respone in string format. 
 * Uses the third party jar,HTTPClient.jar, for communicating with Zoho service.
 * 
 * @version 1.0
 */
public class URLDataHandler
{
    private static String hostAddress = null;
    public static boolean rememberCookie = false;
    
    //Catalina home
    private static String catalinaHome = System.getProperty("catalina.home");
    
    //File separator
    private static String fileSep = File.separator;

    //Location of proxySettings.conf
/*    private static String configFile = catalinaHome+fileSep+"webapps"+fileSep
        +"zoho"+fileSep+"WEB-INF"+fileSep+"classes"+fileSep+"resources"
        +fileSep+"proxySettings.conf"; */

    private static String configFile = "userSettings.conf";
    
    //Stores the proxy configurations
    private static Properties proxyProps = URLDataHandler.getProxyConfigurations();
     
    //
    static
    {
        try
        {
            initSSLFactory();
            CookieModule.setCookiePolicyHandler(null);
            hostAddress = java.net.InetAddress.getLocalHost().getHostAddress();
        }catch(Exception e)
        {
        }
        //sosticket = getTicket();
    }

    //
    private static void initSSLFactory()
    {

        TrustManager[] trustAllCerts = new TrustManager[]
        {
            new X509TrustManager() {

                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public boolean isClientTrusted(
                        java.security.cert.X509Certificate[] certs) {
                    return true;
                        }
                public boolean isServerTrusted(
                        java.security.cert.X509Certificate[] certs) {
                    return true;
                        }
            }
        };

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            // con.setSSLSocketFactory(sc.getSocketFactory());
            HTTPConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    
    /**
     * Executes the given URL(urlStr) and gives back the respone.
     * This method internally calls the {@link #getResponseFromURL}. 
     *
     * @param service - service name.
     * @param userName - user name.
     * @param ticket - Ticket.
     * @param xmlStr - XML string.
     * @param urlStr - URL to be executed
     * @param type - method type(GET/POST)
     * @return String - executes the URL and returns the response.
     */
    public static String getDataFromURL(String service,String userName,String ticket, String xmlStr,String urlStr,String type) throws Exception
    {
        Properties rsp = null;
        String respStr = "";
        //try
        {
            rsp = getResponseFromURL(service,userName,ticket, xmlStr,urlStr,type);
            respStr = rsp.getProperty("response");
            if(rsp == null )
            {
                rsp = getResponseFromURL(service,userName,ticket, xmlStr,urlStr,type);
            }else 
            {
                /*if(!checkCode(respStr) )
                  {
                  }*/
            }
        }/*catch(Exception e)
        {
            throw e;
        }*/        
        return respStr;
    }
    
    /**
     * Executes the given URL(urlStr) and gives back the respone.
     *
     * @param service - service name.
     * @param userName - user name.
     * @param ticket - Ticket.
     * @param xmlStr - XML string.
     * @param urlStr - URL to be executed
     * @param type - method type(GET/POST)
     * @return String - executes the URL and returns the response.
     */
    public static Properties getResponseFromURL(String service,String userName,String ticket, String xmlStr,String urlStr,String type) throws Exception
    {
            System.out.println("URL "+urlStr);
        long tt=System.currentTimeMillis();   
        Properties prop = new Properties();
        //System.out.println("URLDataHandler::getResponseFromURL:::Service:"+service
        //        +"* UserName:"+userName+"* Ticket:"+ticket+":"+xmlStr+"*");
        //try
        {
            //System.out.println("xmlStr "+xmlStr);
            URL url = new URL(urlStr);

            HTTPClient.URI uri = new HTTPClient.URI(url);
            HTTPConnection con = new HTTPConnection(uri);
            HTTPResponse   rsp = null;
            if(!rememberCookie)
            {
                HTTPClient.CookieModule.discardAllCookies();
            }

            //Configured proxy details
            int timeOut = 5000;
            //If the proxyProps was not intialized,intializes the same
            //here
            if(proxyProps == null)
            {
                proxyProps = getProxyConfigurations();
            }

            if(proxyProps != null)
            {
                boolean isProxyEnabled = false;
                String timeOutCnf = proxyProps.getProperty("requestTimeout");
                if(timeOutCnf != null && !timeOutCnf.trim().equals(""))
                {
                    try
                    {
                        timeOut = Integer.parseInt(timeOutCnf);
                    }
                    catch(Exception e)
                    {
                        System.out.println("URLDataHandler::Exception in"+
                            " parsing configured timeout value:"+timeOutCnf);    
                    }
                }

                String isPrxyEnbld = proxyProps.getProperty("isProxyEnabled");
                if(isPrxyEnbld != null && isPrxyEnbld.equals("true"))
                {
                    isProxyEnabled = true;
                }
                if(isProxyEnabled)
                {
                    String host = proxyProps.getProperty("host");
                    int port = 80;
                    try
                    {
                        port = Integer.parseInt(proxyProps.getProperty("port"));
                    }
                    catch(Exception e)
                    {
                        System.out.println("URLDataHandler::Exception in "+
                            "parsing the configured port value::"+
                            proxyProps.getProperty("port")+".So current"+
                            " port value is::"+port);    
                    }
                    String realm = proxyProps.getProperty("realm");
                    String user_Name = proxyProps.getProperty("username");
                    String password = proxyProps.getProperty("password");
                    if(host != null && !host.trim().equals("") 
                            && user_Name != "" && !user_Name.trim().equals("") 
                            && password != "" && !password.trim().equals("")
                            && realm != null && !realm.trim().equals(""))
                    {
                          con.setCurrentProxy(host,port);
                          AuthorizationInfo.addBasicAuthorization(host,port, realm , user_Name , password );
                    }
                    else
                    {
                        System.out.println("URLDataHandler::Configured Proxy details"+
                                " are not proper in the userSettings.conf. "+
                                "So no proxy is set.");    
                    }
                }
                else
                {
                    //System.out.println("URLDataHandler:: No proxy has been set****************");    
                }
            }
            //System.out.println("URLDataHandler::Timeout set::"+timeOut);    
            con.setTimeout(timeOut);
            //

            
            if(xmlStr == null)
            {
                type = "GET";
            }
            if(type.equals("POST"))
            {
                //System.out.println("URLDataHandler:getResponseFromURL:POST");    
                rsp = con.Post(url.getFile(), xmlStr);
            }else if(type.equals("FORMPOST"))
            {
                //System.out.println("URLDataHandler:getResponseFromURL:FORMPOST:::");    
                HTTPClient.NVPair [] formelements = null;
                ArrayList list = new ArrayList(); // Contains all the formdata
                StringTokenizer  tokens = new StringTokenizer(xmlStr,"&");
                while(tokens.hasMoreTokens())
                {
                    String keyvalue = tokens.nextToken();
                    StringTokenizer keyvaluetokens = new StringTokenizer(keyvalue,"=");
                    String paramname = "";
                    String paramvalue= "";

                    while(keyvaluetokens.hasMoreTokens())
                    {
                        paramname = "";
                        paramvalue= "";
                        paramname = keyvaluetokens.nextToken();
                        paramvalue = keyvaluetokens.nextToken();

                    }
                    HTTPClient.NVPair nvpair = new HTTPClient.NVPair(paramname,paramvalue);
                    list.add(nvpair);
                }

                formelements = new HTTPClient.NVPair[list.size()];

                // Below for loop converts list into array
                for(int i=0;i<list.size();i++)
                {
                    formelements[i]=(HTTPClient.NVPair)list.get(i);
                }
                HTTPClient.NVPair nvpair = new HTTPClient.NVPair("Pragma","no-cache");
                HTTPClient.NVPair headers [] =new HTTPClient.NVPair[]{nvpair};
                rsp = con.Post(url.getFile(),formelements,headers);
            }else
            {
                rsp = con.Get(url.getFile());
                //System.out.println("URLDataHandler:GET::RESP::"+rsp);    
            }

            String resp ="NODATA";
            System.out.println("getStatusCode "+rsp);
             System.out.println("getStatusCode "+rsp.getText());

            if (rsp.getStatusCode() >= 300)
            {
                System.err.println("Received Error: "+rsp.getReasonLine());
                System.err.println(rsp.getText());
            }
            else
            {
                //    resp = rsp.getText();
                String response = new String(rsp.getData(),"UTF-8");
                resp = response;
                /*    if(service != null && !service.equals(""))
                    {
                //        writeFile(service,userName,resp);    System.out.println("resp "+resp);
                }*/
            }
            prop.setProperty("response",resp);
            prop.setProperty("statusCode",rsp.getStatusCode()+"");
        }/*catch(InterruptedIOException ie)
        {
            System.err.println("Error handling request: " + ie.getMessage());
            throw ie;    
        }
        catch(UnknownHostException ee)
        {
            System.err.println("Error handling request: " + ee.getMessage());
            throw ee;    
        }
        catch (Exception e)
        {
            System.err.println("Error handling request: " + e.getMessage());
            throw e;    
        }finally{
        }*/

        tt=System.currentTimeMillis()-tt;
        System.out.println("timetaken for HTTPClient response rajarajan:"+tt); 
        return prop;
    }

    /**
     * Reads the userSettings.conf file and returns the configured
     * details in Properties object.
     * userSettings.conf file is read from the location: 
     *   <tomcat_home>/webapps/ea/WEB-INF/classes/resources
     */
    private static Properties getProxyConfigurations()
    {
        Class c=null;
        Properties prop = null;
        try
        {
            c = Class.forName("com.util.URLDataHandler");
            InputStream s = c.getClassLoader().getResourceAsStream(configFile);
            prop = new Properties();
            prop.load(s);
        }
        catch(Exception e)
        {
            System.out.println("URLDataHandler:getProxyConfigurations:"+
                    "Exception while parsing the userSettings.conf");    
            e.printStackTrace();    
        }
        System.out.println("URLDataHandler:getProxyConfigurations:"+
                "ConfiguredProxyDetails::"+prop);    
        return prop;
    }
public static Properties getUserSettings()
{
  return proxyProps;
}    

}
