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

#include "echo_util.h"
#include <axis2_util.h>
#include <axiom_soap.h>
#include <axis2_client.h>

#define MAX_COUNT  10

/* my on_complete callback function */
axis2_status_t AXIS2_CALL echo_callback_on_complete(
    struct axis2_callback * callback,
    const axutil_env_t * env);

/* my on_error callback function */
axis2_status_t AXIS2_CALL echo_callback_on_error(
    struct axis2_callback *callback,
    const axutil_env_t * env,
    int exception);

/* to check whether the callback is completed */
int isComplete = 0;

int
main(
    int argc,
    char **argv)
{
    const axutil_env_t *env = NULL;
    const axis2_char_t *address = NULL;
    axis2_endpoint_ref_t *endpoint_ref = NULL;
    axis2_endpoint_ref_t *reply_to = NULL;
    axis2_options_t *options = NULL;
    const axis2_char_t *client_home = NULL;
    axis2_svc_client_t *svc_client = NULL;
    axiom_node_t *payload = NULL;
    axis2_callback_t *callback = NULL;
    int count = 0;

    /* Set up the environment */
    env =
        axutil_env_create_all("echo_non_blocking_dual_amqp.log",
                              AXIS2_LOG_LEVEL_TRACE);

    /* Set end point reference of echo service */
    address = "amqp://localhost:5672/axis2/services/echo";
    if (argc > 1)
        address = argv[1];
    if (axutil_strcmp(address, "-h") == 0)
    {
        printf("Usage : %s [endpoint_url]\n", argv[0]);
        printf("use -h for help\n");
        return 0;
    }
    printf("Using endpoint : %s\n", address);

    /* Create EPR with given address */
    endpoint_ref = axis2_endpoint_ref_create(env, address);

    /* Setup options */
    options = axis2_options_create(env);
    axis2_options_set_to(options, env, endpoint_ref);
    axis2_options_set_use_separate_listener(options, env, AXIS2_TRUE);

    /* Seperate listner needs addressing, hence addressing stuff in options */
    axis2_options_set_action(options, env,
                             "http://ws.apache.org/axis2/c/samples/echoString");
    reply_to =
        axis2_endpoint_ref_create(env,
                                  "amqp://localhost:5672/axis2/services/__ANONYMOUS_SERVICE__");
    axis2_options_set_reply_to(options, env, reply_to);

	axis2_options_set_transport_in_protocol(options, env, AXIS2_TRANSPORT_ENUM_AMQP);

    /* Set up deploy folder. It is from the deploy folder, the configuration is picked up
     * using the axis2.xml file.
     * In this sample client_home points to the Axis2/C default deploy folder. The client_home can 
     * be different from this folder on your system. For example, you may have a different folder 
     * (say, my_client_folder) with its own axis2.xml file. my_client_folder/modules will have the 
     * modules that the client uses
     */
    client_home = AXIS2_GETENV("AXIS2C_HOME");
    if (!client_home || !strcmp(client_home, ""))
        client_home = "../..";

    /* Create service client */
    svc_client = axis2_svc_client_create(env, client_home);
    if (!svc_client)
    {
        printf
            ("Error creating service client, Please check AXIS2C_HOME again\n");
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "Stub invoke FAILED: Error code:" " %d :: %s",
                        env->error->error_number,
                        AXIS2_ERROR_GET_MESSAGE(env->error));
        return -1;
    }

    /* Set service client options */
    axis2_svc_client_set_options(svc_client, env, options);

    axis2_svc_client_engage_module(svc_client, env, AXIS2_MODULE_ADDRESSING);
    /*axis2_svc_client_engage_module(svc_client, env, "sandesha2"); */

    /* Build the SOAP request message payload using OM API. */
    payload = build_om_payload_for_echo_svc(env);

    /* Create the callback object with default on_complete and on_error
       callback functions */
    callback = axis2_callback_create(env);

    /* Set our on_complete fucntion pointer to the callback object */
    axis2_callback_set_on_complete(callback, echo_callback_on_complete);

    /* Set our on_error function pointer to the callback object */
    axis2_callback_set_on_error(callback, echo_callback_on_error);

    /* Send request */
    axis2_svc_client_send_receive_non_blocking(svc_client, env,
                                               payload, callback);

    /** Wait till callback is complete. Simply keep the parent thread running
       until our on_complete or on_error is invoked */
    while (count < MAX_COUNT)
    {
        if (isComplete)
        {
            /* We are done with the callback */
            break;
        }
		
		AXIS2_SLEEP(1);
        count++;
    }

    if (!(count < MAX_COUNT))
    {
        printf("\necho client invoke FAILED. Counter timed out.\n");
    }

    if (svc_client)
    {
        AXIS2_SLEEP(1);
        axis2_svc_client_free(svc_client, env);
        svc_client = NULL;
    }

    if (env)
    {
        axutil_env_free((axutil_env_t *) env);
        env = NULL;
    }

    return 0;
}

axis2_status_t AXIS2_CALL
echo_callback_on_complete(
    struct axis2_callback * callback,
    const axutil_env_t * env)
{

    /** SOAP response has arrived here; get the soap envelope
      from the callback object and do whatever you want to do with it */

    axiom_soap_envelope_t *soap_envelope = NULL;
    axiom_node_t *ret_node = NULL;
    axis2_status_t status = AXIS2_SUCCESS;

    soap_envelope = axis2_callback_get_envelope(callback, env);

    if (!soap_envelope)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "Stub invoke FAILED: Error code:" " %d :: %s",
                        env->error->error_number,
                        AXIS2_ERROR_GET_MESSAGE(env->error));
        printf("echo stub invoke FAILED!\n");
        status = AXIS2_FAILURE;
    }
    else
    {
        ret_node = axiom_soap_envelope_get_base_node(soap_envelope, env);

        if (!ret_node)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "Stub invoke FAILED: Error code:" " %d :: %s",
                            env->error->error_number,
                            AXIS2_ERROR_GET_MESSAGE(env->error));
            printf("echo stub invoke FAILED!\n");
            status = AXIS2_FAILURE;
        }
        else
        {
            axis2_char_t *om_str = NULL;
            om_str = axiom_node_to_string(ret_node, env);
            if (om_str)
                printf("\nReceived OM : %s\n", om_str);
            printf("\necho client invoke SUCCESSFUL!\n");
        }
    }
    isComplete = 1;
    return status;
}

axis2_status_t AXIS2_CALL
echo_callback_on_error(
    struct axis2_callback * callback,
    const axutil_env_t * env,
    int exception)
{

    /** take necessary action on error */
    printf("\nEcho client invoke FAILED. Error code:%d ::%s", exception,
           AXIS2_ERROR_GET_MESSAGE(env->error));
    isComplete = 1;
    return AXIS2_SUCCESS;
}
