/*
 * 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.client;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.async.AxisCallback;
import org.apache.axis2.client.async.Callback;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.ClientUtils;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.util.TargetResolver;
import org.apache.axis2.wsdl.WSDLConstants;

import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;

/**
 * An operation client is the way an advanced user interacts with Axis2. Actual
 * operation clients understand a specific MEP and hence their behavior is
 * defined by their MEP. To interact with an operation client, you first get one
 * from a specific AxisOperation. Then you set the messages into it one by one
 * (whatever is available). Then, when you call execute() the client will
 * execute what it can at that point. If executing the operation client results
 * in a new message being created, then if a message receiver is registered with
 * the client then the message will be delivered to that client.
 */
public abstract class OperationClient {

    protected AxisOperation axisOp;

    protected ServiceContext sc;

    protected Options options;

    protected OperationContext oc;

    protected Callback callback;

    protected AxisCallback axisCallback;

    /*
    * indicates whether the MEP execution has completed (and hence ready for
    * resetting)
    */
    protected boolean completed;

    protected OperationClient(AxisOperation axisOp, ServiceContext sc, Options options) {
        this.axisOp = axisOp;
        this.sc = sc;
        this.options = new Options(options);
        completed = false;
        oc = sc.createOperationContext(axisOp);
    }

    /**
     * Sets the options that should be used for this particular client. This
     * resets the entire set of options to use the new options - so you'd lose
     * any option cascading that may have been set up.
     *
     * @param options the options
     */
    public void setOptions(Options options) {
        this.options = options;
    }

    /**
     * Return the options used by this client. If you want to set a single
     * option, then the right way is to do getOptions() and set specific
     * options.
     *
     * @return the options, which will never be null.
     */
    public Options getOptions() {
        return options;
    }

    /**
     * Add a message context to the client for processing. This method must not
     * process the message - it only records it in the operation client.
     * Processing only occurs when execute() is called.
     *
     * @param messageContext the message context
     * @throws AxisFault if this is called inappropriately.
     */
    public abstract void addMessageContext(MessageContext messageContext) throws AxisFault;

    /**
     * Return a message from the client - will return null if the requested
     * message is not available.
     *
     * @param messageLabel the message label of the desired message context
     * @return the desired message context or null if its not available.
     * @throws AxisFault if the message label is invalid
     */
    public abstract MessageContext getMessageContext(String messageLabel)
            throws AxisFault;

    /**
     * Set the callback to be executed when a message comes into the MEP and the
     * operation client is executed. This is the way the operation client
     * provides notification that a message has been received by it. Exactly
     * when its executed and under what conditions is a function of the specific
     * operation client.
     *
     * @param callback the callback to be used when the client decides its time to
     *                 use it
     * @deprecated Please use the AxisCallback interface rather than Callback, which has been deprecated
     */
    public abstract void setCallback(Callback callback);

    /**
     * Set the callback to be executed when a message comes into the MEP and the
     * operation client is executed. This is the way the operation client
     * provides notification that a message has been received by it. Exactly
     * when its executed and under what conditions is a function of the specific
     * operation client.
     *
     * @param callback the callback to be used when the client decides its time to
     *                 use it
     */
    public final void setCallback(AxisCallback callback) {
        axisCallback = callback;
    }

    /**
     * Execute the MEP.  This method is final and only serves to set (if appropriate)
     * the lastOperationContext on the ServiceContext, and then it calls
     * executeImpl(), which does the actual work.
     *
     * @param block Indicates whether execution should block or return ASAP. What
     *              block means is of course a function of the specific operation
     *              client.
     * @throws AxisFault if something goes wrong during the execution of the operation
     *                   client.
     */
    public final void execute(boolean block) throws AxisFault {
        sc.setLastOperationContext(oc);
        executeImpl(block);
    }

    /**
     * Execute the MEP. What this does depends on the specific operation client.
     * The basic idea is to have the operation client execute and do something
     * with the messages that have been added to it so far. For example, if its
     * an Out-In MEP, then if the Out message has been set, then executing the
     * client asks it to send the message and get the In message, possibly using
     * a different thread.
     *
     * @param block Indicates whether execution should block or return ASAP. What
     *              block means is of course a function of the specific operation
     *              client.
     * @throws AxisFault if something goes wrong during the execution of the operation
     *                   client.
     */
    public abstract void executeImpl(boolean block) throws AxisFault;

    /**
     * Reset the operation client to a clean status after the MEP has completed.
     * This is how you can reuse an operation client. NOTE: this does not reset
     * the options; only the internal state so the client can be used again.
     *
     * @throws AxisFault if reset is called before the MEP client has completed an
     *                   interaction.
     */
    public void reset() throws AxisFault {
        if (!completed) {
            throw new AxisFault(Messages.getMessage("cannotreset"));
        }
        oc = null;
        completed = false;
    }


    /**
     * To close the transport if necessary , can call this method. The main
     * usage of this method is when client uses two tarnsports for sending and
     * receiving , and we need to remove entries for waiting calls in the
     * transport listener queue.
     * Note : DO NOT call this method if you are not using two transports to
     * send and receive
     *
     * @param msgCtxt : MessageContext# which has all the transport information
     * @throws AxisFault : throws AxisFault if something goes wrong
     */
    public void complete(MessageContext msgCtxt) throws AxisFault {
        TransportOutDescription trsout = msgCtxt.getTransportOut();
        if (trsout != null) {
            trsout.getSender().cleanup(msgCtxt);
        }
    }


    /**
     * To get the operation context of the operation client
     *
     * @return OperationContext
     */
    public OperationContext getOperationContext() {
        return oc;
    }

    /**
     * Create a message ID for the given message context if needed. If user gives an option with
     * MessageID then just copy that into MessageContext , and with that there can be multiple
     * message with same MessageID unless user call setOption for each invocation.
     * <p/>
     * If user want to give message ID then the better way is to set the message ID in the option and
     * call setOption for each invocation then the right thing will happen.
     * <p/>
     * If user does not give a message ID then the new one will be created and set that into Message
     * Context.
     *
     * @param mc the message context whose id is to be set
     */
    protected void setMessageID(MessageContext mc) {
        // now its the time to put the parameters set by the user in to the
        // correct places and to the
        // if there is no message id still, set a new one.
        String messageId = options.getMessageId();
        if (messageId == null || "".equals(messageId)) {
            messageId = UUIDGenerator.getUUID();
        }
        mc.setMessageID(messageId);
    }

    protected void addReferenceParameters(MessageContext msgctx) {
        EndpointReference to = msgctx.getTo();
        if (options.isManageSession() || (options.getParent() != null &&
                options.getParent().isManageSession())) {
            EndpointReference tepr = sc.getTargetEPR();
            if (tepr != null) {
                Map<QName, OMElement> map = tepr.getAllReferenceParameters();
                if (map != null) {
                    Iterator<OMElement> valuse = map.values().iterator();
                    while (valuse.hasNext()) {
                        Object refparaelement = valuse.next();
                        if (refparaelement instanceof OMElement) {
                            to.addReferenceParameter((OMElement) refparaelement);
                        }
                    }
                }
            }
        }
    }

    /**
     * prepareMessageContext gets a fresh new MessageContext ready to be sent.
     * It sets up the necessary properties, transport information, etc.
     *
     * @param configurationContext the active ConfigurationContext
     * @param mc the MessageContext to be configured
     * @throws AxisFault if there is a problem
     */
    protected void prepareMessageContext(ConfigurationContext configurationContext,
                                         MessageContext mc)
            throws AxisFault {
        // set options on the message context
        if (mc.getSoapAction() == null || "".equals(mc.getSoapAction())) {
            mc.setSoapAction(options.getAction());
        }

        mc.setOptions(new Options(options));
        mc.setAxisMessage(axisOp.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE));

        // do Target Resolution
        TargetResolver targetResolver =
                configurationContext.getAxisConfiguration().getTargetResolverChain();
        if (targetResolver != null) {
            targetResolver.resolveTarget(mc);
        }
        // if the transport to use for sending is not specified, try to find it
        // from the URL
        TransportOutDescription senderTransport = options.getTransportOut();
        if (senderTransport == null) {
            EndpointReference toEPR = (options.getTo() != null) ? options
                    .getTo() : mc.getTo();
            senderTransport = ClientUtils.inferOutTransport(configurationContext
                    .getAxisConfiguration(), toEPR, mc);
        }
        mc.setTransportOut(senderTransport);
        if (options.getParent() !=null && options.getParent().isManageSession()) {
            mc.getOptions().setManageSession(true);
        } else if (options.isManageSession()) {
            mc.getOptions().setManageSession(true);
        }
        addReferenceParameters(mc);
    }
}
