/*
 * 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 jakarta.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();

    }

}
