#include <stdio.h>
#include <stdlib.h>

#include <axiom.h>
#include <axiom_xpath.h>
#include <axiom_namespace.h>
#include <axis2_util.h>
#include <axiom_soap.h>
#include <axis2_client.h>

#include "proxy.h"


#define WS_URL "http://mellbourn.com/WebServices/PasswordGeneratorWebService/PasswordGeneratorService.asmx"


int main(int argc, char *argv[])
{
	const axutil_env_t *env = NULL;
	const axis2_char_t *axis2_home = NULL;
	axis2_endpoint_ref_t *endpoint_ref = NULL;
	axis2_svc_client_t *svc_client = NULL;
	axis2_options_t *options = NULL;
	char *proxy_host;
	int proxy_port;
	axiom_node_t *top_node = NULL, *node = NULL, *ret_node = NULL;
	axiom_element_t *top_elt = NULL, *elt = NULL, *ret_elt = NULL;
	axiom_namespace_t *ns;
	axis2_char_t *buffer;
	axis2_char_t *pwd;
	axis2_char_t *elt_name;
	axutil_qname_t *qname_result;
	/* The axutil_string_create_const() is strange. */
	axis2_char_t *SOAP_ACTION;
	

	printf("AXIS2C_HOME=%s\nhttp_proxy=%s\n", getenv("AXIS2C_HOME"), getenv("http_proxy"));

 
	env = axutil_env_create_all("./pwgen.log", AXIS2_LOG_LEVEL_TRACE);
	if (env->error->error_number)
		printf("env_create_all failure %d: %s\n", env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));

	axis2_home = AXIS2_GETENV("AXIS2C_HOME");
	if (env->error->error_number)
		printf("AXIS2_GETENV failure %d: %s\n", env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));

	svc_client = axis2_svc_client_create(env, axis2_home);
	if (env->error->error_number) {
		printf("axis2_svc_client_create failure %d: %s\n", env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));
		env->error->error_number = 0;
	}

	if (get_proxy(WS_URL, &proxy_host, &proxy_port)) {
		char proxy_port_str[10];
		sprintf(proxy_port_str, "%d", proxy_port);
		printf("Proxy: %s %s\n", proxy_host, proxy_port_str);
		axis2_svc_client_set_proxy(svc_client, env, proxy_host, proxy_port_str);
		/* free(proxy_host); proxy_host = NULL; */
	}

	options = axis2_options_create(env);
	endpoint_ref = axis2_endpoint_ref_create(env, WS_URL);
	axis2_options_set_to(options, env, endpoint_ref);
	axis2_options_set_soap_version(options, env, AXIOM_SOAP11);
	axis2_options_set_soap_action(options, env, axutil_string_create_const(env, &SOAP_ACTION));

	axis2_svc_client_set_options(svc_client, env, options);
	if (env->error->error_number)
		printf("Failure %d: %s\n", env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));

	top_elt = axiom_element_create(env, NULL, "get_Password", NULL, &top_node);
	ns = axiom_element_declare_default_namespace(top_elt, env, "http://www.mellbourn.com/WebServices/");

	buffer = axiom_node_to_string(top_node, env);
	printf("Request XML:\n%s\n", buffer);
	AXIS2_FREE(env->allocator, buffer);

	ret_node = axis2_svc_client_send_receive(svc_client, env, top_node);
	if (env->error->error_number)
		printf("svc_client_send_receive failure %d: %s\n", env->error->error_number, AXIS2_ERROR_GET_MESSAGE(env->error));

	if (ret_node == NULL) {
		printf("ret_node=NULL\n");
	} else {
		ret_elt = (axiom_element_t *)axiom_node_get_data_element(ret_node, env);
		elt_name = axiom_element_get_localname(ret_elt, env);
		printf("%s\n", elt_name);
        	if (axis2_svc_client_get_last_response_has_fault(svc_client, env)) {
			if (strcmp(elt_name, "Fault") == 0) {
				axutil_qname_t *qname_faultcode = axutil_qname_create(env, "faultcode", NULL, NULL);
				axutil_qname_t *qname_faultstr = axutil_qname_create(env, "faultstring", NULL, NULL);
				elt = axiom_element_get_first_child_with_qname(ret_elt, env, qname_faultcode, ret_node, &node);
				if (elt)
					printf("faultcode: %s\n", axiom_element_get_text(elt, env, node));
				elt = axiom_element_get_first_child_with_qname(ret_elt, env, qname_faultstr, ret_node, &node);
				if (elt)
					printf("faultstring: %s\n", axiom_element_get_text(elt, env, node));
			}
		} else {
			qname_result = axutil_qname_create_from_string(env,
				"get_PasswordResult|http://www.mellbourn.com/WebServices/");
				
			elt = axiom_element_get_first_child_with_qname(ret_elt, env, qname_result, ret_node, &node);
			axutil_qname_free(qname_result);
			if (elt) {
				pwd = axiom_element_get_text(elt, env, node);
				puts(pwd);
			}
		}
	}
	axiom_node_free_tree(ret_node, env);

	axis2_svc_client_free(svc_client, env);

	axutil_env_free((axutil_env_t *) env);

	return 0;
}


