/*
 * 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 googleserverweb;

import java.util.Date;
import java.util.Iterator;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import java.io.Serializable;
import java.rmi.RemoteException; 
import javax.naming.*;
import javax.xml.rpc.Service;
import javax.xml.rpc.server.ServiceLifecycle;
import javax.xml.namespace.QName;

public class GoogleServletImpl implements javax.servlet.SingleThreadModel, ServiceLifecycle {

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

    public GoogleServletImpl() {
        System.out.println("GoogleServletImpl() instantiated");
    }

    public void init(Object context) {
        System.out.println("Got ServiceLifecycle::init call " + context);
        gotInit = true;
    }

    public void destroy() {
        System.out.println("Got ServiceLifecycle::destroy call");
    }

    public byte[] doGetCachedPage(java.lang.String key, java.lang.String url) 
    { 
        return null; 
    }

    public void helloOneWay(String s1) {

        System.out.println("In GoogleServletImpl::helloOneWay. param = " +
                           s1);
        System.out.println("Sleeping for " + s1 + " milliseconds starting "
                           + " at " + new Date());

        try {
            Thread.sleep((new Integer(s1)).intValue());
        } catch(Exception e) {
            e.printStackTrace();
        }
        System.out.println("Exiting GoogleServletImpl:helloOneWay at " +
                           new Date());
    }

    public String doSpellingSuggestion(java.lang.String key, 
                                       java.lang.String phrase) 

        throws RemoteException {
        System.out.println("GoogleServletImpl.doSpellingSuggestion() " +
                           " called with " + phrase);

        if( !gotInit ) {
            throw new RuntimeException("Got business method before init()");
        }

        String returnValue = "spelling suggestion from web";
        if( phrase.equals("forwardejb") ) {
            System.out.println("Forwarding spelling suggestion to ejbendpoint");
            Service genericServiceWithWSDL = null;
            try {
                InitialContext ic = new InitialContext();
                Service service = (Service) 
                    ic.lookup("java:comp/env/service/EjbDIIReference");
                doDynamicProxyTest(service);
                GoogleSearchPort ejbPort = (GoogleSearchPort) 
                    service.getPort(GoogleSearchPort.class);
                returnValue = ejbPort.doSpellingSuggestion(key, phrase);
            } catch(Exception e) {
                e.printStackTrace();
                throw new RemoteException(e.getMessage(), e);
            }
        }               
        
        System.out.println("GoogleServletImpl returning " + returnValue);
        return returnValue;
    }
        
    public GoogleSearchResult doGoogleSearch(java.lang.String key, java.lang.String q, int start, int maxResults, boolean filter, java.lang.String restrict, boolean safeSearch, java.lang.String lr, java.lang.String ie, java.lang.String oe) {
        return null;
    }

    private void doDynamicProxyTest(Service service) 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);

        // 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();
        
    }
    
}
