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

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.engine.Pingable;
import org.apache.axis2.receivers.AbstractInOutMessageReceiver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Iterator;

public class PingMessageReceiver extends AbstractInOutMessageReceiver implements PingConstants {
    private static Log log = LogFactory.getLog(PingMessageReceiver.class);

    public void invokeBusinessLogic(MessageContext inMessage, MessageContext outMessage) throws AxisFault {

        try {
            int operationStatus;
            AxisOperation axisOperation;
            PingResponse pingResponse = new PingResponse();
            pingResponse.initPingResponse(inMessage);
            Iterator<AxisOperation> opListIterator = getAxisOperations(inMessage);

            while (opListIterator.hasNext()) {
                axisOperation = (AxisOperation) opListIterator.next();

                if (!PING_METHOD_NAME.equals(axisOperation.getName().getLocalPart())) {
                    operationStatus = invokePingableMR(inMessage, axisOperation);
                    pingResponse.addOperationStatus(axisOperation, operationStatus);
                }
            }

            SOAPEnvelope envelope = pingResponse.getResposeEnvelope();
            outMessage.setEnvelope(envelope);

        } catch (Exception e) {
            String msg = "Exception occurred while trying to ping the service" +
                    inMessage.getAxisService().getName();

            log.error(msg, e);
            throw new AxisFault(msg);
        }
    }

    /**
     * This method identifies whether the ping request is an operation level or a service level one.
     * If it is servicel level, returns the operation iterator from the AxisService
     *
     * @param inMessage
     * @return Iterator for the list of AxisOperations
     * @throws AxisFault
     */
    private Iterator<AxisOperation> getAxisOperations(MessageContext inMessage) throws AxisFault {
        boolean serviceLevel = false;
        Iterator<AxisOperation> operationsIterator;

        OMElement element = null;
        OMElement pingRequestElement = inMessage.getEnvelope().
                getBody().getFirstChildWithName(new QName(TYPE_PING_REQUEST));

        if (pingRequestElement == null) {
            //throw new AxisFault("Ping Request is not specified");
            //SOAP body is null or ping request is not specified
            //This is considered as a service level ping.
            serviceLevel = true;
        } else {
            element = pingRequestElement.getFirstChildWithName(new QName(TAG_OPERATION));
        }


        if (!serviceLevel && element != null) {
            //Operations to be pinged has been specified in the ping request
            Iterator<OMElement> elementIterator = pingRequestElement.getChildrenWithName(new QName(TAG_OPERATION));
            ArrayList<AxisOperation> operationList = new ArrayList<AxisOperation>();
            AxisOperation axisOperation;

            while (elementIterator.hasNext()) {
                OMElement opElement = elementIterator.next();
                String operationName = opElement.getText();
                axisOperation = inMessage.getAxisService().getOperation(new QName(operationName));

                if (axisOperation != null) {
                    operationList.add(axisOperation);
                } else {
                    String msg = "Operation not found: " + operationName +
                            " specified in the ping request for the service" +
                            inMessage.getAxisService().getName();
                    log.error(msg);
                    throw new AxisFault(msg);
                }
            }
            operationsIterator = operationList.iterator();
        } else {
            //No operation is mentioned in the request.. So this is a service level ping
            operationsIterator = inMessage.getAxisService().getOperations();
        }
        return operationsIterator;
    }

    /**
     * This method checks whether the MessageReceiver is Pingable
     * If it is Pingable invoke the ping() method after setting the operation name to be pinged as property.
     *
     * @param axisOperation
     * @return
     * @throws AxisFault
     */
    private int invokePingableMR(MessageContext inMessage, AxisOperation axisOperation) throws AxisFault {
        MessageReceiver msgReceiver = axisOperation.getMessageReceiver();

        if (msgReceiver != null && msgReceiver instanceof Pingable) {
            Pingable pingableMR = (Pingable) msgReceiver;
            //Adding the operation name to be pinged as a property
            inMessage.setProperty(Pingable.OPERATION_TO_PING, axisOperation.getName().getLocalPart());
            return pingableMR.ping();
        }

        return Pingable.PING_MODULE_LEVEL;
    }
}
