
/*
 * 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>
#include <axis2_http_transport.h>

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_options_t *options = NULL;
    const axis2_char_t *client_home = NULL;
    axis2_svc_client_t *svc_client = NULL;
    axiom_node_t *payload = NULL;
    axiom_node_t *ret_node = NULL;
    axis2_bool_t method_get = AXIS2_FALSE;
    axis2_bool_t method_head = AXIS2_FALSE;
    axis2_bool_t method_put = AXIS2_FALSE;
    axis2_bool_t method_delete = AXIS2_FALSE;

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

    /* Set end point reference of echo service */
    address = "http://localhost:9090/axis2/services/echo/echoString";
    if (argc > 1)
    {
        if (0 == strncmp(argv[1], "-mGET", 5))
        {
            method_get = AXIS2_TRUE;
        }
        else if (0 == strncmp(argv[1], "-mHEAD", 6))
        {
            method_head = AXIS2_TRUE;
        }
        else if (0 == strncmp(argv[1], "-mPUT", 5))
        {
            method_put = AXIS2_TRUE;
        }
        else if (0 == strncmp(argv[1], "-mDELETE",8 ))
        {
            method_delete = AXIS2_TRUE;
        }
        else if (0 == axutil_strcmp(argv[1], "-h"))
        {
            printf("Usage : %s [endpoint_url] \n", argv[0]);
            printf("\nNOTE: You can test for other HTTP methods by changing the");
            printf(" services.xml of the echo service\n and providing the correct REST HTTP method");
            printf(" and the location to be used for operation.\n");
            printf(" Also note that you have to restart the server after changing the services.xml.\n");
            printf(" use %s -mGET for HTTP GET\n", argv[0]);
            printf(" use %s -mHEAD for HTTP HEAD\n", argv[0]);
            printf(" use %s -mDELETE for HTTP DELETE\n", argv[0]);
            printf(" use %s -mPUT for HTTP PUT\n", argv[0]);
            printf(" use -h for help\n");
            return 0;
        }
        else
        {
            address = argv[1];
        }
    }

    if (argc > 2)
    {
        if (0 == strncmp(argv[2], "-mGET", 5))
        {
            method_get = AXIS2_TRUE;
        }
        else if (0 == strncmp(argv[2], "-mHEAD", 6))
        {
            method_head = AXIS2_TRUE;
        }
        else if (0 == strncmp(argv[2], "-mPUT", 5))
        {
            method_put = AXIS2_TRUE;
        }
        else if (0 == strncmp(argv[2], "-mDELETE",8 ))
        {
            method_delete = AXIS2_TRUE;
        }
        else
        {
            address = argv[2];
        }
    }

    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);
    /* Enable REST at the client side */
    axis2_options_set_enable_rest(options, env, AXIS2_TRUE);

    if (AXIS2_TRUE == method_get)
    {
        axis2_options_set_http_method(options, env, AXIS2_HTTP_GET);
    }
    else if (AXIS2_TRUE == method_head)
    {
        axis2_options_set_http_method(options, env, AXIS2_HTTP_HEAD);
    }
    else if (AXIS2_TRUE == method_put)
    {
        axis2_options_set_http_method(options, env, AXIS2_HTTP_PUT);
    }
    else if (AXIS2_TRUE == method_delete)
    {
        axis2_options_set_http_method(options, env, AXIS2_HTTP_DELETE);
    }
    /* 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);

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

    /* Send request */
    ret_node = axis2_svc_client_send_receive(svc_client, env, payload);

    if (ret_node && 
        axis2_svc_client_get_last_response_has_fault(svc_client, env))
    {
        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);
            AXIS2_FREE(env->allocator, om_str);
        }
        printf("\necho client invoke FAILED!\n");
    }
    else if (ret_node)
    {
        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);
            AXIS2_FREE(env->allocator, om_str);
        }
        printf("\necho client invoke SUCCESSFUL!\n");
    }
    else if (method_head &&
        axis2_svc_client_get_last_response_has_fault(svc_client, env))
    {
        /* HEAD request should probably be removed from this file,
         * and be relocated to transport unit tests.
         */
        printf("\necho client invoke FAILED!\n");
    }
    else if (method_head)
    {
        /* HEAD request should probably be removed from this file,
         * and be relocated to transport unit tests.
         */
        printf("\necho client invoke SUCCESSFUL!\n");
    }
    else
    {
        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 client invoke FAILED!\n");
    }

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

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