package gov.epa.state.sample.client;

import gov.epa.cdx.commons.log.LogInterface;
import gov.epa.cdx.commons.log.LogFactory;
import gov.epa.cdx.axis.v10.client.NodeRequestor;

import java.net.URL;
import java.net.MalformedURLException;
import java.math.BigInteger;
import java.util.Properties;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.Security;

// libraries imported per Calvin's request
import com.sun.net.ssl.internal.www.protocol.https.*;
import com.sun.net.ssl.internal.ssl.Provider;

/**

 * User: David Dundua
 * Date: May 29, 2003
 * Time: 11:17:38 AM
 */
public class Client
{
    private static LogInterface log = LogFactory.getLog(Client.class.getName());
    private static String TARGET_URL;

    static
    {
        //this adds SSL provider
        //for the client we are going to add a JSSE Provider
//        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        //we need to set the SSLSocketFactory to ignore invalid server side certs
//        Security.setProperty( "ssl.SocketFactory.provider", "gov.epa.state.sample.DummySSLSocketFactory");

        // above lines commented out per Calvin's request.  Added two following lines
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");


        Client.loadProperties();
    }

    private static URL validateAndReturnURL(String URLString)
    {
        URL url = null;
        try
        {
            url = new URL(URLString);
        }
        catch (MalformedURLException ex)
        {
            new Exception(URLString + " is malformed URL. Fatal exception.");
        }

        return url;
    }

    public static void main(String[] args)
    {
        String USERNAME = "<your_node_user_account>";
        String PASSWORD = "<node_user_password>";
        String DATAFLOWTYPE = "TEST"; // "FRS";
        String DOCUMENTNAME = "testSubmit.xml";
        String DOCUMENTTYPE = "XML";
//        String SERVICEREQUEST ="GetFacilityByName";
        String SERVICEREQUEST ="GetFacilityByChangeDate";
//        String [] SERVICEPARAMETERVALUES = {"ME", "A%"};
        String [] SERVICEPARAMETERVALUES = {"ME", "2002-09-17"};
        String SERVICETYPE = "Query";

        NodeRequestor requestor = null;

        try
        {
            //please note we are going over https
            URL url = validateAndReturnURL(TARGET_URL);
            log.debug("[client]: Using URL " + url.toString() );
            requestor = new NodeRequestor(url);

            //first lets ping
            String response = requestor.nodePing("hello");
            log.debug("[nodePing]: Recieved response " + response );

            String token = requestor.authenticate(USERNAME, PASSWORD);
            log.debug("[authenticate]: Recieved security token " + token );

            byte[] byteArray = {111, 111};
            String transactionId =
                    requestor.submit(token, null, DATAFLOWTYPE, DOCUMENTNAME, DOCUMENTTYPE, byteArray);
            log.debug("[submit]: Recieved transactionId from submit " + transactionId );


            //check status of submited document
            String status =
                    requestor.getStatus(token, transactionId);
            log.debug("[getStatus]: Status of transaction " + transactionId + " is " + status );

            //download the document that was just submitted
            // The Maine node is not set up with the use case of a user being able to come back
            // and retrieve a previously submitted document.  Therefore have repaced
            // transactionId with a null.
            byte[] documentConent = requestor.download(token, null, DATAFLOWTYPE, DOCUMENTNAME, DOCUMENTTYPE);
            log.debug("[download]: Recieved document of size  " + documentConent.length + " bytes." );

             long startTime = System.currentTimeMillis();
            //lets perform query agains FRS
            byte[] queryResultContent =
                    requestor.query(token, SERVICEREQUEST, new BigInteger("0"), new BigInteger("-1"), SERVICEPARAMETERVALUES);
            long took = System.currentTimeMillis() - startTime;
            log.debug("The query took " + took + "ms.");
            log.debug("[query]: Begin:" );
            String output = new String (queryResultContent);
            log.debug(output);
            log.debug("[query]: End");

            //perform solicit
            String returnUrl = new String("https://oradev.bis.state.me.us:4445/node/services/NetworkNodePortType_V10");
//            String returnUrl = new String("https://test.epacdxnode.net/cdx/services/NetworkNodePortType_V10");
            String solicitTransactionId =
                    requestor.solicit(token, returnUrl, SERVICEREQUEST,  SERVICEPARAMETERVALUES);
            log.debug("[solicit]: Recieved transactionId from solicit " + solicitTransactionId );

            //notify
            String notifyTransaction =
                    requestor.notify(token, null, DATAFLOWTYPE,  DOCUMENTNAME, DOCUMENTTYPE);
            log.debug("[notify]: Recieved transactionId from notify " + notifyTransaction );

            //get list services
            String [] services =
                    requestor.getServices(token, SERVICETYPE);
            log.debug("[getServices]: List of supported services: ");
            for (int counter = 0; counter < services.length; counter++) {
                String service = services[counter];
                log.debug(counter + " " + service);
            }
            log.debug("[getServices]: End of List of supported services.");


        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

    }


    private static void loadProperties()
    {
        String fileName = "Locator.properties";
        String DEFAULT_URL = "https://epacdxnode.net/cdx/services/NetworkNodePortType_V10";
        Properties prop = new Properties();
        try
        {
            prop.load(new FileInputStream(fileName));
        }
        catch (FileNotFoundException ex)
        {
            log.info("File "+ fileName + " not found. Make sure you place that file in the same directory");
            log.info("Using default URL: " + DEFAULT_URL);

        }
        catch (IOException exc)
        {
            log.info("Error reading properties file " +fileName + "check to make sure contents are properly formed. ");
            log.info("Using default URL: " + DEFAULT_URL);
        }

        TARGET_URL = prop.getProperty("CLIENT_TARGET_URL", DEFAULT_URL);
    }
}
