
/*
 * 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_soap_fault_value.h>
#include "_axiom_soap_fault_sub_code.h"
#include "_axiom_soap_fault_code.h"
#include <axiom_element.h>
#include <axiom_text.h>

struct axiom_soap_fault_value
{

    /** store om element node */
    axiom_node_t *om_ele_node;
};

AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL
axiom_soap_fault_value_create(
    const axutil_env_t * env)
{
    axiom_soap_fault_value_t *fault_value = NULL;

    fault_value = (axiom_soap_fault_value_t *) AXIS2_MALLOC(env->allocator,
                                                            sizeof
                                                            (axiom_soap_fault_value_t));

    if (!fault_value)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                          "No memory. Cannot create SOAP fault value");
        return NULL;
    }

    fault_value->om_ele_node = NULL;

    return fault_value;
}

AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL
axiom_soap_fault_value_create_with_subcode(
    const axutil_env_t * env,
    axiom_soap_fault_sub_code_t * parent)
{
    axiom_soap_fault_value_t *fault_value = NULL;

    axiom_element_t *this_ele = NULL;
    axiom_node_t *this_node = NULL;
    axiom_namespace_t *parent_ns = NULL;
    axiom_node_t *parent_node = NULL;
    axiom_element_t *parent_ele = NULL;
    int soap_version = -1;

    AXIS2_PARAM_CHECK(env->error, parent, NULL);

    fault_value = axiom_soap_fault_value_create(env);

    if (!fault_value)
    {
        return NULL;
    }

    parent_node = axiom_soap_fault_sub_code_get_base_node(parent, env);

    if (!parent_node)
    {
        axiom_soap_fault_value_free(fault_value, env);
        return NULL;
    }

    parent_ele = (axiom_element_t *)
        axiom_node_get_data_element(parent_node, env);

    if (!parent_ele)
    {
        axiom_soap_fault_value_free(fault_value, env);
        return NULL;
    }
    soap_version = axiom_soap_fault_sub_code_get_soap_version(parent, env);
    if (soap_version == AXIOM_SOAP12)
    {
        parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node);
    }

    this_ele = axiom_element_create(env,
                                    parent_node,
                                    AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME,
                                    parent_ns, &this_node);

    if (!this_ele)
    {
        axiom_soap_fault_value_free(fault_value, env);
        return NULL;
    }

    fault_value->om_ele_node = this_node;

    axiom_soap_fault_sub_code_set_value(parent, env, fault_value);

    return fault_value;
}

AXIS2_EXTERN axiom_soap_fault_value_t *AXIS2_CALL
axiom_soap_fault_value_create_with_code(
    const axutil_env_t * env,
    axiom_soap_fault_code_t * parent)
{
    axiom_soap_fault_value_t *fault_value = NULL;
    int soap_version = -1;
    axiom_element_t *this_ele = NULL;
    axiom_node_t *this_node = NULL;
    axiom_namespace_t *parent_ns = NULL;
    axiom_node_t *parent_node = NULL;
    axiom_element_t *parent_ele = NULL;

    AXIS2_PARAM_CHECK(env->error, parent, NULL);

    fault_value = axiom_soap_fault_value_create(env);

    if (!fault_value)
    {
        return NULL;
    }

    parent_node = axiom_soap_fault_code_get_base_node(parent, env);
    if (!parent_node)
    {
        axiom_soap_fault_value_free(fault_value, env);
        return NULL;
    }
    parent_ele = (axiom_element_t *)
        axiom_node_get_data_element(parent_node, env);
    if (!parent_ele)
    {
        axiom_soap_fault_value_free(fault_value, env);
        return NULL;
    }
    soap_version = axiom_soap_fault_code_get_soap_version(parent, env);
    if (soap_version == AXIOM_SOAP12)
    {
        parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node);
    }
    this_ele = axiom_element_create(env,
                                    parent_node,
                                    AXIOM_SOAP12_SOAP_FAULT_VALUE_LOCAL_NAME,
                                    parent_ns, &this_node);

    if (!this_ele)
    {
        axiom_soap_fault_value_free(fault_value, env);
        return NULL;
    }
    fault_value->om_ele_node = this_node;

    axiom_soap_fault_code_set_value(parent, env, fault_value);

    return fault_value;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_soap_fault_value_free(
    axiom_soap_fault_value_t * fault_value,
    const axutil_env_t * env)
{
    AXIS2_FREE(env->allocator, fault_value);
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_fault_value_set_base_node(
    axiom_soap_fault_value_t * fault_value,
    const axutil_env_t * env,
    axiom_node_t * node)
{

    if (node && (axiom_node_get_node_type(node, env) != AXIOM_ELEMENT))
    {
        AXIS2_HANDLE_ERROR(env,
                        AXIS2_ERROR_INVALID_BASE_TYPE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    fault_value->om_ele_node = node;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_soap_fault_value_get_base_node(
    axiom_soap_fault_value_t * fault_value,
    const axutil_env_t * env)
{
    return fault_value->om_ele_node;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_soap_fault_value_get_text(
    axiom_soap_fault_value_t * fault_value,
    const axutil_env_t * env)
{
    axiom_node_t *value_node = NULL;
    axiom_element_t *value_element = NULL;

    value_node = axiom_soap_fault_value_get_base_node(fault_value, env);

    if (!value_node)
    {
        return NULL;
    }
    value_element =
        (axiom_element_t *) axiom_node_get_data_element(value_node, env);

    if (!value_element)
    {
        return NULL;
    }
    return axiom_element_get_text(value_element, env, value_node);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_fault_value_set_text(
    axiom_soap_fault_value_t * fault_value,
    const axutil_env_t * env,
    axis2_char_t * text)
{
    AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE);
    if (fault_value->om_ele_node &&
        axiom_node_get_node_type(fault_value->om_ele_node,
                                 env) == AXIOM_ELEMENT)
    {
        axiom_element_t *om_ele = NULL;
        om_ele = (axiom_element_t *)
            axiom_node_get_data_element(fault_value->om_ele_node, env);
        return axiom_element_set_text(om_ele, env, text,
                                      fault_value->om_ele_node);
    }
    return AXIS2_FAILURE;
}
