/*
 * 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 <axiom_text.h>
#include <axiom_output.h>
#include <axutil_string.h>
#include "axiom_node_internal.h"
#include <axiom_xml_writer.h>
#include <axiom_output.h>
#include <axiom_attribute.h>
#include <axiom_namespace.h>
#include <axutil_base64.h>

static axis2_bool_t AXIS2_CALL axiom_text_get_is_binary(
    axiom_text_t * om_text,
    const axutil_env_t * env);

static axis2_status_t AXIS2_CALL axiom_text_serialize_start_part(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    axiom_output_t * om_output);

struct axiom_text
{

    /** Text value */
    axutil_string_t *value;

    /** The following fields are for MTOM */
    axis2_char_t *mime_type;
    axis2_bool_t optimize;
    axis2_bool_t is_binary;
    axis2_bool_t is_swa;
    axis2_char_t *content_id;
    axiom_attribute_t *om_attribute;
    axiom_namespace_t *ns;
    axiom_data_handler_t *data_handler;
};

AXIS2_EXTERN axiom_text_t *AXIS2_CALL
axiom_text_create(
    const axutil_env_t * env,
    axiom_node_t * parent,
    const axis2_char_t * value,
    axiom_node_t ** node)
{
    axiom_text_t *om_text = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, node, NULL);

    *node = axiom_node_create(env);

    if(!(*node))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    om_text = (axiom_text_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_text_t));
    if(!om_text)
    {
        AXIS2_FREE(env->allocator, *node);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    om_text->mime_type = NULL;
    om_text->optimize = AXIS2_FALSE;
    om_text->is_binary = AXIS2_FALSE;
    om_text->is_swa = AXIS2_FALSE;
    om_text->content_id = NULL;
    om_text->om_attribute = NULL;
    om_text->value = NULL;
    om_text->ns = NULL;
    om_text->data_handler = NULL;
    om_text->mime_type = NULL;

    if(value)
    {
        om_text->value = axutil_string_create(env, value);
    }

    axiom_node_set_data_element((*node), env, om_text);
    axiom_node_set_node_type((*node), env, AXIOM_TEXT);
    axiom_node_set_complete((*node), env, AXIS2_FALSE);

    if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT)
    {
        axiom_node_add_child(parent, env, (*node));
    }

    return om_text;
}

AXIS2_EXTERN axiom_text_t *AXIS2_CALL
axiom_text_create_with_data_handler(
    const axutil_env_t * env,
    axiom_node_t * parent,
    axiom_data_handler_t * data_handler,
    axiom_node_t ** node)
{

    axiom_text_t *om_text = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, data_handler, NULL);

    om_text = (axiom_text_t *)axiom_text_create(env, parent, NULL, node);
    if(!om_text)
    {
        return NULL;
    }
    om_text->optimize = AXIS2_TRUE;
    om_text->is_binary = AXIS2_TRUE;
    om_text->data_handler = data_handler;
    om_text->mime_type = axiom_data_handler_get_content_type(data_handler, env);
    return om_text;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_text_free(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, void);

    if(om_text->value)
    {
        axutil_string_free(om_text->value, env);
    }

    if(om_text->ns)
    {
        axiom_namespace_free(om_text->ns, env);
    }

    if(om_text->content_id)
    {
        AXIS2_FREE(env->allocator, om_text->content_id);
    }

    if(om_text->om_attribute)
    {
        axiom_attribute_free(om_text->om_attribute, env);
    }

    if(om_text->data_handler)
    {
        axiom_data_handler_free(om_text->data_handler, env);
    }

    AXIS2_FREE(env->allocator, om_text);
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_serialize(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{
    int status = AXIS2_SUCCESS;
    axis2_char_t *attribute_value = NULL;
    const axis2_char_t *text = NULL;
    axiom_xml_writer_t *om_output_xml_writer = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE);

    if(!axiom_text_get_is_binary(om_text, env))
    {
        if(om_text->value)
        {
            status = axiom_output_write(om_output, env, AXIOM_TEXT, 1, axutil_string_get_buffer(
                om_text->value, env));
        }
    }
    else
    {
        om_output_xml_writer = axiom_output_get_xml_writer(om_output, env);
        if(axiom_output_is_optimized(om_output, env) && om_text->optimize)
        {
            if(!(axiom_text_get_content_id(om_text, env)))
            {
                axis2_char_t *content_id = axiom_output_get_next_content_id(om_output, env);
                if(content_id)
                {
                    om_text->content_id = axutil_strdup(env, content_id);
                }
            }

            attribute_value = axutil_stracat(env, "cid:", om_text->content_id);

            /*send binary as MTOM optimised */
            if(om_text->om_attribute)
            {
                axiom_attribute_free(om_text->om_attribute, env);
                om_text->om_attribute = NULL;
            }

            om_text->om_attribute = axiom_attribute_create(env, "href", attribute_value, NULL);

            AXIS2_FREE(env->allocator, attribute_value);
            attribute_value = NULL;

            if(!om_text->is_swa) /* This is a hack to get SwA working */
            {
                axiom_text_serialize_start_part(om_text, env, om_output);
            }
            else
            {
                status = axiom_output_write(om_output, env, AXIOM_TEXT, 1, om_text->content_id);
            }

            axiom_output_write_optimized(om_output, env, om_text);

            axiom_output_write(om_output, env, AXIOM_ELEMENT, 0);
        }
        else
        {
            text = axiom_text_get_text(om_text, env);
            axiom_xml_writer_write_characters(om_output_xml_writer, env, (axis2_char_t *)text);
        }
    }
    return status;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axiom_text_get_value(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    if(om_text->value)
    {
        return axutil_string_get_buffer(om_text->value, env);
    }
    return NULL;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_value(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    const axis2_char_t * value)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE);

    if(om_text->value)
    {
        axutil_string_free(om_text->value, env);
        om_text->value = NULL;
    }

    om_text->value = axutil_string_create(env, value);
    if(!om_text->value)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

/*Following has been implemented for the MTOM support*/

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_text_get_mime_type(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    return om_text->mime_type;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_mime_type(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    const axis2_char_t * mime_type)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE);
    if(om_text->mime_type)
    {
        AXIS2_FREE(env->allocator, om_text->mime_type);
    }
    om_text->mime_type = (axis2_char_t *)axutil_strdup(env, mime_type);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_text_get_optimize(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    return om_text->optimize;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_optimize(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    axis2_bool_t optimize)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE);
    om_text->optimize = optimize;
    return AXIS2_SUCCESS;
}

static axis2_bool_t AXIS2_CALL
axiom_text_get_is_binary(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    return om_text->is_binary;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_is_binary(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    const axis2_bool_t is_binary)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE);
    om_text->is_binary = is_binary;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_text_get_content_id(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    return om_text->content_id;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_content_id(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    const axis2_char_t * content_id)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE);
    if(om_text->content_id)
    {
        AXIS2_FREE(env->allocator, om_text->content_id);
    }
    om_text->content_id = (axis2_char_t *)axutil_strdup(env, content_id);
    return AXIS2_SUCCESS;
}

static axis2_status_t AXIS2_CALL
axiom_text_serialize_start_part(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{
    axis2_char_t *namespace_uri = NULL;
    axis2_char_t *prefix = NULL;
    const axis2_char_t *local_name = NULL;
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    local_name = "Include";

    om_text->ns = axiom_namespace_create(env, "http://www.w3.org/2004/08/xop/include", "xop");

    if(om_text->ns)
    {
        namespace_uri = axiom_namespace_get_uri(om_text->ns, env);
        if(namespace_uri)
        {
            prefix = axiom_namespace_get_prefix(om_text->ns, env);

            if(prefix)
            {
                axiom_output_write(om_output, env, AXIOM_ELEMENT, 3, local_name, namespace_uri,
                    prefix);
            }
            else
            {
                axiom_output_write(om_output, env, AXIOM_ELEMENT, 2, local_name, namespace_uri);
            }
        }
        else
        {
            axiom_output_write(om_output, env, AXIOM_ELEMENT, 1, local_name);
        }
    }
    else
    {
        axiom_output_write(om_output, env, AXIOM_TEXT, 1, local_name);
    }
    if(om_text->om_attribute)
    {
        axiom_attribute_serialize(om_text->om_attribute, env, om_output);
    }
    if(om_text->ns)
    {
        axiom_namespace_serialize(om_text->ns, env, om_output);
        axiom_namespace_free(om_text->ns, env);
        om_text->ns = NULL;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_serialize_attribute(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    axiom_output_t * om_output,
    axiom_attribute_t * om_attribute)
{
    axiom_xml_writer_t *xml_writer = NULL;
    axiom_namespace_t *om_namespace = NULL;

    axis2_char_t *namespace_uri = NULL;
    axis2_char_t *prefix = NULL;
    axis2_char_t *attribute_local_name = NULL;
    axis2_char_t *attribute_value = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
        AXIS2_XML_PARSER_TYPE_BUFFER);
    om_namespace = axiom_namespace_create(env, "", "");

    namespace_uri = axiom_namespace_get_uri(om_text->ns, env);
    attribute_local_name = axiom_attribute_get_localname(om_attribute, env);

    if(om_namespace)
    {
        prefix = axiom_namespace_get_prefix(om_text->ns, env);
        attribute_value = axiom_attribute_get_value(om_attribute, env);
        if(prefix)
        {
            axiom_xml_writer_write_attribute(xml_writer, env, attribute_local_name, attribute_value);
        }
        else
        {
            axiom_xml_writer_write_attribute_with_namespace(xml_writer, env, attribute_local_name,
                attribute_value, namespace_uri);
        }
    }
    else
    {
        axiom_xml_writer_write_attribute(xml_writer, env, attribute_local_name, attribute_value);
    }
    axiom_namespace_free(om_namespace, env);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_serialize_namespace(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    const axiom_namespace_t * om_namespace,
    axiom_output_t * om_output)
{
    axiom_xml_writer_t *xml_writer = NULL;
    axis2_char_t *namespace_uri = NULL;
    axis2_char_t *namespace_prefix = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0,
        AXIS2_XML_PARSER_TYPE_BUFFER);
    om_namespace = axiom_namespace_create(env, "", "");

    if(om_namespace)
    {
        namespace_uri = axiom_namespace_get_uri(om_text->ns, env);
        namespace_prefix = axiom_namespace_get_prefix(om_text->ns, env);
        axiom_xml_writer_write_namespace(xml_writer, env, namespace_prefix, namespace_uri);
        axiom_xml_writer_set_prefix(xml_writer, env, namespace_prefix, namespace_uri);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axiom_text_get_text(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    if(om_text->value)
    {
        return axutil_string_get_buffer(om_text->value, env);
    }
    else
    {
        axis2_char_t *data_handler_stream = NULL;
        size_t data_handler_stream_size = 0;
        if(om_text->data_handler)
        {
            int encoded_len = 0;
            axis2_char_t *encoded_str = NULL;
            axiom_data_handler_read_from(om_text->data_handler, env, &data_handler_stream,
                &data_handler_stream_size);
            if(data_handler_stream)
            {
                encoded_len = axutil_base64_encode_len((int)data_handler_stream_size);
                encoded_str = AXIS2_MALLOC(env->allocator, encoded_len + 2);
                if(encoded_str)
                {
                    encoded_len = axutil_base64_encode(encoded_str, data_handler_stream,
                        (int)data_handler_stream_size);
                    encoded_str[encoded_len] = '\0';
                    return encoded_str;
                }
            }
        }
    }
    return NULL;
}

AXIS2_EXTERN axiom_data_handler_t *AXIS2_CALL
axiom_text_get_data_handler(
    axiom_text_t * om_text,
    const axutil_env_t * env)
{
    return om_text->data_handler;
}

AXIS2_EXTERN axiom_text_t *AXIS2_CALL
axiom_text_create_str(
    const axutil_env_t * env,
    axiom_node_t * parent,
    axutil_string_t * value,
    axiom_node_t ** node)
{
    axiom_text_t *om_text = NULL;
    AXIS2_PARAM_CHECK(env->error, node, NULL);

    *node = axiom_node_create(env);
    if(!(*node))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unable to create node needed by om text");
        return NULL;
    }

    om_text = (axiom_text_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_text_t));
    if(!om_text)
    {
        AXIS2_FREE(env->allocator, *node);
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Insufficient memory to create om text");
        return NULL;
    }

    memset(om_text, 0, sizeof(axiom_text_t));
    if(value)
    {
        om_text->value = axutil_string_clone(value, env);
    }

    axiom_node_set_data_element((*node), env, om_text);
    axiom_node_set_node_type((*node), env, AXIOM_TEXT);

    if(parent && axiom_node_get_node_type(parent, env) == AXIOM_ELEMENT)
    {
        axiom_node_add_child(parent, env, (*node));
    }

    return om_text;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_value_str(
    struct axiom_text * om_text,
    const axutil_env_t * env,
    axutil_string_t * value)
{
    if(om_text->value)
    {
        axutil_string_free(om_text->value, env);
        om_text->value = NULL;
    }
    if(value)
    {
        om_text->value = axutil_string_clone(value, env);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axiom_text_get_value_str(
    struct axiom_text * om_text,
    const axutil_env_t * env)
{
    return om_text->value;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_text_set_is_swa(
    axiom_text_t * om_text,
    const axutil_env_t * env,
    const axis2_bool_t is_swa)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_text, AXIS2_FAILURE);
    om_text->is_swa = is_swa;
    return AXIS2_SUCCESS;
}
