/*
 * Copyright (c) 2002, 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 googleclient;

import java.io.*;
import java.util.*;
import java.net.URL;
import javax.naming.*;
import javax.xml.namespace.QName;
import javax.xml.rpc.Stub;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import java.rmi.Remote;
import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;

public class Client {

    private static SimpleReporterAdapter stat = 
        new SimpleReporterAdapter("appserv-tests");

    private static final QName PORT_QNAME = 
        new QName("urn:GoogleSearch", "GoogleSearchPort");
    private static final QName OPERATION_QNAME =
        new QName("urn:GoogleSearch", "doSpellingSuggestion");

    private String word;
    private String targetEndpointAddress;

    public static void main (String[] args) {

        stat.addDescription("googleserver appclient");	
        Client client = new Client(args);
        client.doTest();
        stat.printSummary("googleserver-applientID");
    }
    
    public Client(String[] args) {
        word = (args.length > 0) ? args[0] : "spellng";
        targetEndpointAddress = (args.length > 1) ? args[1] : null;
    }

    public void doTest() {

    	try {
            Context ic = new InitialContext();
            String googleKey = (String)
                ic.lookup("java:comp/env/googlekey");
            GoogleSearchService googleSearchService = (GoogleSearchService)
                    ic.lookup("java:comp/env/service/GoogleSearch");

            try {
                googleSearchService.getHandlerRegistry();
            } catch(java.lang.UnsupportedOperationException uoe) {
                System.out.println
                    ("Successfully caught unsupported operation exception " +
                     "for Service.getHandlerRegistry()");
            }

            try {
                googleSearchService.getTypeMappingRegistry();
            } catch(java.lang.UnsupportedOperationException uoe) {
                System.out.println
                    ("Successfully caught unsupported operation exception " +
                     "for Service.getTypeMappingRegistry()");
            }

            doDynamicProxyTest(googleSearchService, googleKey);

            GoogleSearchPort googleSearchPort = 
                googleSearchService.getGoogleSearchPort();
            doSpellingSuggestion(googleSearchPort, googleKey,
                                 targetEndpointAddress);

            System.out.println("Using dynamic proxy to invoke endpoint");
            Service genericServiceWithWsdl = (Service)
                ic.lookup("java:comp/env/service/GoogleSearchProxy");

            doDynamicProxyTest(genericServiceWithWsdl, googleKey);

            googleSearchPort = (GoogleSearchPort)
                genericServiceWithWsdl.getPort(GoogleSearchPort.class);
            doSpellingSuggestion(googleSearchPort, googleKey,
                                 targetEndpointAddress);

            doDIINoWSDLTest(ic, googleKey, targetEndpointAddress);

            System.out.println("Doing wsdl override tests");

            Service partialWsdlServiceGeneric = (Service)
                ic.lookup("java:comp/env/service/partialGeneric");
            GoogleSearchPort googleSearch = (GoogleSearchPort)
                partialWsdlServiceGeneric.getPort(GoogleSearchPort.class);
            googleSearch.doSpellingSuggestion(googleKey, word);

/**            GoogleSearchService partialWsdlServiceGenerated = 
                (GoogleSearchService)
                ic.lookup("java:comp/env/service/partialGenerated");
            googleSearch = partialWsdlServiceGenerated.getGoogleSearchPort();
            googleSearch.doSpellingSuggestion(googleKey, word);
**/
            stat.addStatus("appclient main", stat.PASS);


    	} catch (Exception ex) {
            System.out.println("google client test failed");
            ex.printStackTrace();
            stat.addStatus("appclient main" , stat.FAIL);
	} 

    }

    private void doSpellingSuggestion(GoogleSearchPort googleSearchPort,
                                      String googleKey,
                                      String endpointAddress) 
        throws Exception {

        if( endpointAddress != null ) {
            ((Stub)googleSearchPort)._setProperty
                (Stub.ENDPOINT_ADDRESS_PROPERTY, targetEndpointAddress);
            System.out.println("Setting target endpoint address to " +
                               endpointAddress);
        } else {
            // if not set, use default
            endpointAddress = (String)
                ((Stub)googleSearchPort)._getProperty
                (Stub.ENDPOINT_ADDRESS_PROPERTY);
        }

        System.out.println("Contacting google for spelling " +
                           "suggestion at " + endpointAddress);
        
        String spellingSuggestion =
            googleSearchPort.doSpellingSuggestion(googleKey, word);
        System.out.println("Gave google the word '" + word + "' ... " +
                           " and the suggested spelling is '" +
                           spellingSuggestion + "'");
    }

    private void doDynamicProxyTest(Service service, String googleKey) throws Exception {

        Call c1 = service.createCall();
        Call c2 = service.createCall(PORT_QNAME);
        Call c3 = service.createCall(PORT_QNAME, OPERATION_QNAME);
        Call c4 = service.createCall(PORT_QNAME, 
                                     OPERATION_QNAME.getLocalPart());
        Call[] calls = service.getCalls(PORT_QNAME);

        if( targetEndpointAddress != null ) {
            c3.setTargetEndpointAddress(targetEndpointAddress);            
        } 
        Object params[] = new Object[] {googleKey, "hello" };
        String response = (String) c3.invoke(params);
        System.out.println("Response = " + response);

        // container-managed port selection
        GoogleSearchPort sei = (GoogleSearchPort) 
            service.getPort(GoogleSearchPort.class);
        sei = (GoogleSearchPort) 
            service.getPort(PORT_QNAME, GoogleSearchPort.class);

        QName serviceName = service.getServiceName();
        URL wsdlLocation = service.getWSDLDocumentLocation();
        if( wsdlLocation != null ) {
            System.out.println("wsdlLocation = " + wsdlLocation);
        }
        Iterator ports = service.getPorts();

        System.out.println("Calling oneway operation");
        Call oneway = service.createCall(PORT_QNAME, "helloOneWay");
        if( targetEndpointAddress != null ) {
            oneway.setTargetEndpointAddress(targetEndpointAddress);            
        } 

        long oneWayMethodWaitTimeInMillis = 7000;

        Date before = new Date();        
        oneway.invokeOneWay(new Object[] 
               { oneWayMethodWaitTimeInMillis + "" });
        Date after = new Date();
        long elapsedTime = after.getTime() - before.getTime();
        System.out.println("one way operation began at " + before + 
                           " and returned at " + after + 
                           " and took " +  elapsedTime + " milli-seconds");
        if( elapsedTime > oneWayMethodWaitTimeInMillis ) {
            throw new Exception("one way operation blocked for too long ");
        }

        // now wait for the remainder of the time.  this is to
        // avoid race conditions where we finish the test and begin
        // to undeploy, but the endpoint is still executing its
        // oneway operation.
        long sleepTime = (oneWayMethodWaitTimeInMillis - elapsedTime);
                          
        System.out.println("now sleeping for " + sleepTime + " milli secs");
        Thread.sleep(sleepTime);
        System.out.println("returning from doDynamicProxyTest");
    }

    private void doDIINoWSDLTest(Context ic, String googleKey,
                                 String endpointAddress) throws Exception {

        System.out.println("Doing DII without WSDL tests");

        Service service =(Service) ic.lookup("java:comp/env/service/DIINoWSDL");

        try {
            Call call = service.createCall(PORT_QNAME);
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.createCall(QName port)");
        }

        try {
            Call call = service.createCall(PORT_QNAME, OPERATION_QNAME);
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getCall(QName, QName)");
        }


        try {
            Call call = service.createCall(PORT_QNAME, "doSpellingSuggestion");
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getCall(QName, String)");
        }

        try {
            Call[] calls = service.getCalls(PORT_QNAME);
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getCalls()");
        }

        try {
            service.getHandlerRegistry();
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println
                ("Successfully caught unsupported operation exception " +
                 "for Service.getHandlerRegistry()");
        }

        try {
            Remote remote = service.getPort(GoogleSearchPort.class);
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getPort(SEI)");
        }
        
        try {
            Remote remote = service.getPort(PORT_QNAME, GoogleSearchPort.class);
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getPort(QName, SEI)");
        }

        try {
            Iterator ports = service.getPorts();
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getPorts()");
        }

        try {
            QName serviceName = service.getServiceName();
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println("Successfully caught unsupported operation " +
                               "for Service.getName()");
        }

        try {
            service.getTypeMappingRegistry();
        } catch(java.lang.UnsupportedOperationException uoe) {
            System.out.println
                ("Successfully caught unsupported operation exception " +
                 "for Service.getTypeMappingRegistry()");
        }

        Call untypedCall = service.createCall();

    }
}

