/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.jaxws.core.controller.impl;

import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.core.InvocationContext;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.core.controller.InvocationController;
import org.apache.axis2.jaxws.core.controller.InvocationPattern;
import org.apache.axis2.jaxws.core.util.MessageContextUtils;
import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
import org.apache.axis2.jaxws.handler.SOAPHeadersAdapter;
import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.util.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * An abstract implementation of the InvocationController interface. 
 */
public abstract class InvocationControllerImpl implements InvocationController {

    private static final Log log = LogFactory.getLog(InvocationControllerImpl.class);

    /*
     * (non-Javadoc)
     * @see org.apache.axis2.jaxws.core.controller.InvocationController#invoke(org.apache.axis2.jaxws.core.InvocationContext)
     */
    public InvocationContext invoke(InvocationContext ic) {
        if (log.isDebugEnabled()) {
            log.debug("Invocation pattern: synchronous");
        }

        // Check to make sure we at least have a valid InvocationContext
        // and request MessageContext
        if (ic == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr1"));
        }
        if (ic.getRequestMessageContext() == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr2"));
        }

        MessageContext request = ic.getRequestMessageContext();
        MessageContext response = null;

        request.setProperty(Constants.INVOCATION_PATTERN, InvocationPattern.SYNC);

        // Invoke outbound handlers.
        boolean success =
                HandlerInvokerUtils.invokeOutboundHandlers(request.getMEPContext(),
                                                           ic.getHandlers(),
                                                           HandlerChainProcessor.MEP.REQUEST,
                                                           false);

        if (success) {
            prepareRequest(request);
            response = doInvoke(request);
            prepareResponse(response);
            
            // make sure request and response contexts share a single parent
            response.setMEPContext(request.getMEPContext());

            /*
             * TODO TODO TODO review
             * 
             * In most cases we are adding the endpointDesc to the
             * MessageContext. Notice here that the "response" object is set by
             * the call to doInvoke. It's a new context we are now working with.
             * The invokeInboundHandlers uses that context way down in
             * createMessageContext --> ContextUtils.addProperties()
             * 
             * This may also occur in the AsyncResponse class when calling
             * invokeInboundHandlers
             * 
             * For now, make sure the endpointDesc is set on the response
             * context.
             */
            response.setEndpointDescription(request.getEndpointDescription());

            // Invoke inbound handlers.
            TransportHeadersAdapter.install(response);
            AttachmentsAdapter.install(response);
            SOAPHeadersAdapter.install(response);
            HandlerInvokerUtils.invokeInboundHandlers(response.getMEPContext(),
                                                      ic.getHandlers(),
                                                      HandlerChainProcessor.MEP.RESPONSE,
                                                      false);
        } else { // the outbound handler chain must have had a problem, and
                    // we've reversed directions
            response = MessageContextUtils.createMinimalResponseMessageContext(request);
            // since we've reversed directions, the message has "become a
            // make sure request and response contexts share a single parent
            response.setMEPContext(request.getMEPContext());
            response.setMessage(request.getMessage());
        }
        ic.setResponseMessageContext(response);
        return ic;
    }

    protected abstract MessageContext doInvoke(MessageContext request);

    /*
     * (non-Javadoc)
     * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeOneWay(org.apache.axis2.jaxws.core.InvocationContext)
     */
    public void invokeOneWay(InvocationContext ic) throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Invocation pattern: one-way");
        }

        // Check to make sure we at least have a valid InvocationContext
        // and request MessageContext
        if (ic == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr1"));
        }
        if (ic.getRequestMessageContext() == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr2"));
        }

        MessageContext request = ic.getRequestMessageContext();
        request.setProperty(Constants.INVOCATION_PATTERN, InvocationPattern.ONEWAY);

        // Invoke outbound handlers.
        boolean success =
                HandlerInvokerUtils.invokeOutboundHandlers(request.getMEPContext(),
                                                           ic.getHandlers(),
                                                           HandlerChainProcessor.MEP.REQUEST,
                                                           true);

        if (success) {
            prepareRequest(request);
            doInvokeOneWay(request);
        } else { // the outbound handler chain must have had a problem, and we've reversed directions
            // check to see if problem is due to a handler throwing an exception.  If so, throw it,
            // even in this oneWay invoke.
            Exception e = request.getCausedByException();
            if (e != null) {
                throw (Exception)e.getCause();
            }
        }
        return;
    }

    protected abstract void doInvokeOneWay(MessageContext mc);

    /*
     * (non-Javadoc)
     * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext)
     */
    public Response invokeAsync(InvocationContext ic) {
        if (log.isDebugEnabled()) {
            log.debug("Invocation pattern: asynchronous(polling)");
        }

        // Check to make sure we at least have a valid InvocationContext
        // and request MessageContext
        if (ic == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr1"));
        }
        if (ic.getRequestMessageContext() == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr2"));
        }

        MessageContext request = ic.getRequestMessageContext();
        request.setProperty(Constants.INVOCATION_PATTERN, InvocationPattern.ASYNC_POLLING);

        Response resp = null;

        // Invoke outbound handlers.
        // TODO uncomment, and get the EndpointDescription from the request context, which should soon be available
        boolean success =
                HandlerInvokerUtils.invokeOutboundHandlers(request.getMEPContext(),
                                                           ic.getHandlers(),
                                                           HandlerChainProcessor.MEP.REQUEST,
                                                           false);
        if (success) {
            prepareRequest(request);
            resp = doInvokeAsync(request);
        } else
        { // the outbound handler chain must have had a problem, and we've reversed directions
            // since we've reversed directions, the message has "become a response message" (section 9.3.2.1, footnote superscript 2)

            // TODO we know the message is a fault message, we should
            // convert it to an exception and throw it.
            // something like:

            //throw new AxisFault(request.getMessage());
        }

        return resp;
    }

    public abstract Response doInvokeAsync(MessageContext mc);

    /*
     * (non-Javadoc)
     * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext, javax.xml.ws.AsyncHandler)
     */
    public Future<?> invokeAsync(InvocationContext ic, AsyncHandler asyncHandler) {
        if (log.isDebugEnabled()) {
            log.debug("Invocation pattern: asynchronous(callback)");
        }

        // Check to make sure we at least have a valid InvocationContext
        // and request MessageContext
        if (ic == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr1"));
        }
        if (ic.getRequestMessageContext() == null) {
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr2"));
        }
        if ((ic.getExecutor() != null) && (ic.getExecutor() instanceof ExecutorService)) {
            ExecutorService es = (ExecutorService) ic.getExecutor();
            if (es.isShutdown()) {
                // the executor service is shutdown and won't accept new tasks
                // so return an error back to the client
                throw ExceptionFactory.makeWebServiceException(Messages
                                .getMessage("ExecutorShutdown"));
            }
        }

        MessageContext request = ic.getRequestMessageContext();
        request.setProperty(Constants.INVOCATION_PATTERN, InvocationPattern.ASYNC_CALLBACK);

        Future<?> future = null;

        // Invoke outbound handlers.
        boolean success =
                HandlerInvokerUtils.invokeOutboundHandlers(request.getMEPContext(),
                                                           ic.getHandlers(),
                                                           HandlerChainProcessor.MEP.REQUEST,
                                                           false);
        if (success) {
            prepareRequest(request);
            future = doInvokeAsync(request, asyncHandler);
        } else { // the outbound handler chain must have had a problem, and
                    // we've reversed directions
            // since we've reversed directions, the message has "become a
            // response message" (section 9.3.2.1, footnote superscript 2)

            // TODO: how do we deal with this? The response message may or may
            // not be a fault
            // message. We do know that the direction has reversed, so somehow
            // we need to
            // flow immediately out of the async and give the exception and/or
            // response object
            // back to the client app without calling
            // AsyncResponse.processResponse or processFault
                
            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("invokeAsyncErr"));

            // throw new AxisFault(request.getMessage());
        }
        return future;
    }

    public abstract Future<?> doInvokeAsync(MessageContext mc, AsyncHandler asyncHandler);

    /**
     * Abstract method that must be implemented by whoever is providing the specific client binding.
     *  Once this is called, everything that is needed to invoke the operation must be available in
     * the MessageContext.
     *
     * @param mc
     */
    protected abstract void prepareRequest(MessageContext mc);

    /**
     * Abstract method that must be implemented by whoever is providing the specific client binding.
     *  This is called after the response has come back and allows the client binding to put
     * whatever info it has in the response MessageContext.
     *
     * @param mc
     */
    protected abstract void prepareResponse(MessageContext mc);

}
