#include <stdlib.h>
#include <string.h>

#include <iiimp.h>

#include "input-method.h"


IIIMF_status
iiimf_data_string_ascii_new(
    IIIMP_data_s *	data_s,
    const char *	ptr,
    IIIMP_string **	ret)
{
    IIIMP_string *	str;
    IIIMP_card16 *	p;
    size_t		len;
    size_t		nbyte;
    int			i;

    len = strlen(ptr);
    nbyte = ((sizeof (IIIMP_card16)) * len);

    p = (IIIMP_card16 *)malloc(nbyte);
    if (NULL == p) return IIIMF_STATUS_MALLOC;

    for (i = 0; i < len; i++) {
	*(p + i) = *(ptr + i);
    }

    str = iiimp_string_new(data_s, len, p);
    free(p);

    if (NULL == str) {
	return IIIMF_STATUS_FAIL;
    }

    *ret = str;
    return IIIMF_STATUS_SUCCESS;
}


IIIMF_status
iiimf_data_im_connect(IIIMF_im * im, IIIMP_message ** message_ret)
{
    IIIMF_status	status;
    IIIMP_message *	message;
    IIIMP_string *	user_name;
    IIIMP_string *	auth;
    int			len;
    char *		user;
    char *		password;
    int			user_name_len;
    int			node_len;
    char *		p;

    if (IIIMF_ROLE_CLIENT != im->role) return IIIMF_STATUS_ROLE;

    status = iiimf_role_data_client_auth_password(im, &password);
    if (IIIMF_STATUS_SUCCESS != status) return status;

    user_name_len = strlen(im->role_data.client->user_name);
    node_len = strlen(im->role_data.client->node);

    len = (user_name_len + 1 + node_len + 1 + strlen(password));
    user = (char *)malloc(len + 1);
    if (NULL == user) {
	free(password);
	return IIIMF_STATUS_MALLOC;
    }

    p = user;
    (void)strcpy(p, im->role_data.client->user_name);
    p += user_name_len;
    *p = '@';
    p += 1;
    (void)strcpy(p, im->role_data.client->node);
    p += node_len;
    *p = '#';
    p += 1;
    (void)strcpy(p, password);

    free(password);

    status = iiimf_data_string_ascii_new(im->data_s, user, &user_name);
    free(user);
    if (IIIMF_STATUS_SUCCESS != status) {
	return status;
    }

    auth = NULL;

    message = iiimp_connect_new(im->data_s, user_name, auth);

    if (NULL == message) {
	iiimp_string_delete(im->data_s, user_name);
	return IIIMF_STATUS_FAIL;
    }

    *message_ret = message;

    return IIIMF_STATUS_SUCCESS;
}


IIIMF_status
iiimf_data_client_descriptor(IIIMF_im * im, IIIMP_client_descriptor ** data_ret)
{
    IIIMP_data_s *		data_s;
    IIIMF_status		s_type;
    IIIMF_status		s_os_n;
    IIIMF_status		s_os_a;
    IIIMF_status		s_os_v;
    IIIMF_status		s_X_dn;
    IIIMF_status		s_X_sv;
    IIIMP_client_descriptor *	data;
    IIIMP_string *		type;
    IIIMP_string *		os_name;
    IIIMP_string *		os_arch;
    IIIMP_string *		os_ver;
    IIIMP_string *		X_display_name;
    IIIMP_string *		X_server_vendor;
    IIIMF_role_data_client *	cl;

    if (1 != im->role) return IIIMF_STATUS_ROLE;

    data = NULL;

    s_X_dn = IIIMF_STATUS_SUCCESS;
    s_X_sv = IIIMF_STATUS_SUCCESS;
    X_display_name = NULL;
    X_server_vendor = NULL;

    cl = im->role_data.client;

    data_s = im->data_s;

    s_type = iiimf_data_string_ascii_new(data_s, cl->type, &type);
    s_os_n = iiimf_data_string_ascii_new(data_s, cl->os_name, &os_name);
    s_os_a = iiimf_data_string_ascii_new(data_s, cl->os_arch, &os_arch);
    s_os_v = iiimf_data_string_ascii_new(data_s, cl->os_version, &os_ver);
    if ((NULL != cl->X_display_name) && (NULL != cl->X_server_vendor)) {
	s_X_dn = iiimf_data_string_ascii_new(data_s,
					     cl->X_display_name,
					     &X_display_name);
	s_X_sv = iiimf_data_string_ascii_new(data_s,
					     cl->X_server_vendor,
					     &X_server_vendor);
    }

    data = iiimp_client_descriptor_new(im->data_s,
				       type, os_name, os_arch, os_ver,
				       X_display_name, X_server_vendor);

    if ((IIIMF_STATUS_SUCCESS != s_type) ||
	(IIIMF_STATUS_SUCCESS != s_os_n) ||
	(IIIMF_STATUS_SUCCESS != s_os_a) ||
	(IIIMF_STATUS_SUCCESS != s_os_v) ||
	(IIIMF_STATUS_SUCCESS != s_X_dn) ||
	(IIIMF_STATUS_SUCCESS != s_X_sv) ||
	(NULL == data)) {
	iiimp_string_delete(data_s, type);
	iiimp_string_delete(data_s, os_name);
	iiimp_string_delete(data_s, os_arch);
	iiimp_string_delete(data_s, os_ver);
	iiimp_string_delete(data_s, X_display_name);
	iiimp_string_delete(data_s, X_server_vendor);
	return IIIMF_STATUS_FAIL;
    }

    *data_ret = data;

    return IIIMF_STATUS_SUCCESS;
}


/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
