/*
 * 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_envelope.h"
#include "_axiom_soap_header.h"
#include "_axiom_soap_body.h"
#include <axiom_soap_header_block.h>
#include <axutil_hash.h>
#include <axiom_soap_const.h>
#include <axiom_soap_builder.h>
#include <stdio.h>
#include <axiom_node_internal.h>
#include <axutil_array_list.h>

struct axiom_soap_header
{
    axiom_node_t *om_ele_node;

    int soap_version;

    axutil_hash_t *header_blocks;

    int hbnumber;

    axiom_soap_builder_t *soap_builder;

    axiom_soap_envelope_t *soap_envelope;

    axutil_array_list_t *header_block_keys;
};

static axis2_bool_t AXIS2_CALL axiom_soap_header_qname_matches(
    const axutil_env_t * env,
    axutil_qname_t * element_qname,
    axutil_qname_t * qname_to_match);

AXIS2_EXTERN axiom_soap_header_t *AXIS2_CALL
axiom_soap_header_create(
    const axutil_env_t * env)
{
    axiom_soap_header_t *soap_header = NULL;

    soap_header = (axiom_soap_header_t *)AXIS2_MALLOC(env->allocator, sizeof(axiom_soap_header_t));
    if(!soap_header)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create SOAP header");
        return NULL;
    }

    soap_header->om_ele_node = NULL;
    soap_header->soap_envelope = NULL;
    soap_header->hbnumber = 0;
    soap_header->header_blocks = NULL;

    /** default value */
    soap_header->soap_version = AXIOM_SOAP12;
    soap_header->header_block_keys = NULL;

    soap_header->header_block_keys = axutil_array_list_create(env, 10);
    if(!soap_header->header_block_keys)
    {
        AXIS2_FREE(env->allocator, soap_header);
        return NULL;
    }

    return soap_header;
}

AXIS2_EXTERN axiom_soap_header_t *AXIS2_CALL
axiom_soap_header_create_with_parent(
    const axutil_env_t * env,
    axiom_soap_envelope_t * envelope)
{
    axiom_soap_header_t *soap_header = NULL;

    /*axiom_element_t *this_ele = NULL;
     axiom_node_t *this_node = NULL;*/
    axiom_node_t *body_node = NULL;
    axiom_node_t *parent_node = NULL;
    axiom_element_t *parent_ele = NULL;

    /*axiom_namespace_t *parent_ns = NULL;*/

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

    soap_header = axiom_soap_header_create(env);
    if(!soap_header)
    {
        return NULL;
    }
    soap_header->soap_version = axiom_soap_envelope_get_soap_version(envelope, env);

    parent_node = axiom_soap_envelope_get_base_node(envelope, env);

    if(!parent_node || axiom_node_get_node_type(parent_node, env) != AXIOM_ELEMENT)
    {
        axiom_soap_header_free(soap_header, env);
        return NULL;
    }

    parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
    if(!parent_ele)
    {
        axiom_soap_header_free(soap_header, env);
        return NULL;
    }
    if(axiom_node_get_first_element(parent_node, env))
    {
        body_node = axiom_node_get_first_element(parent_node, env);
        axiom_node_detach(body_node, env);
    }

    /*parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node);
     this_ele = axiom_element_create(env, parent_node,
     AXIOM_SOAP_HEADER_LOCAL_NAME, parent_ns,
     &this_node);
     if (!this_ele)
     {
     axiom_soap_header_free(soap_header, env);
     return NULL;
     }

     soap_header->om_ele_node = this_node;*/

    axiom_soap_envelope_set_header(envelope, env, soap_header);

    if(body_node)
    {
        axiom_node_add_child(parent_node, env, body_node);
    }

    soap_header->soap_envelope = envelope;

    return soap_header;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_soap_header_free(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env)
{

    if(soap_header->header_blocks)
    {
        axutil_hash_index_t *hi = NULL;
        void *val = NULL;
        for(hi = axutil_hash_first(soap_header->header_blocks, env); hi; hi = axutil_hash_next(env,
            hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);

            if(val)
            {
                axiom_soap_header_block_free((axiom_soap_header_block_t *)val, env);
                val = NULL;
            }
        }

        axutil_hash_free(soap_header->header_blocks, env);
    }
    if(soap_header->header_block_keys)
    {
        int size = 0;
        void *val = NULL;
        int i = 0;
        size = axutil_array_list_size(soap_header->header_block_keys, env);
        for(i = 0; i < size; i++)
        {
            val = axutil_array_list_get(soap_header->header_block_keys, env, i);
            if(val)
            {
                AXIS2_FREE(env->allocator, (char *)val);
                val = NULL;
            }
        }
        axutil_array_list_free(soap_header->header_block_keys, env);
        soap_header->header_block_keys = NULL;
    }
    AXIS2_FREE(env->allocator, soap_header);

    soap_header = NULL;

    return;
}

AXIS2_EXTERN axiom_soap_header_block_t *AXIS2_CALL
axiom_soap_header_add_header_block(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    const axis2_char_t * localname,
    axiom_namespace_t * ns)
{
    axiom_soap_header_block_t *header_block = NULL;

    axiom_namespace_t *cloned_ns = NULL;

    axiom_node_t *header_block_node = NULL;

    AXIS2_PARAM_CHECK(env->error, localname, NULL);
    AXIS2_PARAM_CHECK(env->error, ns, NULL);

    cloned_ns = axiom_namespace_clone(ns, env);
    if(!cloned_ns)
    {
        return NULL;
    }
    header_block = axiom_soap_header_block_create_with_parent(env, localname, cloned_ns,
        soap_header);

    if(!header_block)
    {
        return NULL;
    }
    header_block_node = axiom_soap_header_block_get_base_node(header_block, env);

    if(header_block_node)
    {
        axiom_node_set_complete(header_block_node, env, AXIS2_TRUE);

        return header_block;
    }
    else
    {
        return NULL;
    }
}
AXIS2_EXTERN axutil_hash_t *AXIS2_CALL axiom_soap_header_examine_header_blocks(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    axis2_char_t * param_role)
{
    AXIS2_PARAM_CHECK(env->error, param_role, NULL);

    return soap_header->header_blocks;
}

AXIS2_EXTERN axiom_children_qname_iterator_t *AXIS2_CALL
axiom_soap_header_examine_all_header_blocks(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env)
{
    axiom_element_t *om_ele = NULL;

    if(!soap_header->om_ele_node)
    {
        return NULL;
    }
    om_ele = (axiom_element_t *)axiom_node_get_data_element(soap_header-> om_ele_node, env);

    if(om_ele)
    {
        return axiom_element_get_children_with_qname(om_ele, env, NULL, soap_header->om_ele_node);
    }
    else
        return NULL;
}

AXIS2_EXTERN axiom_children_with_specific_attribute_iterator_t *AXIS2_CALL
axiom_soap_header_extract_header_blocks(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    axis2_char_t * role)
{
    const axis2_char_t *localname = NULL;
    const axis2_char_t *nsuri = NULL;

    axiom_node_t *first_node = NULL;
    axiom_element_t *first_ele = NULL;

    axutil_qname_t *qn = NULL;

    axiom_element_t *header_om_ele = NULL;
    axiom_children_with_specific_attribute_iterator_t *iter = NULL;

    if(soap_header->soap_version == AXIOM_SOAP_VERSION_NOT_SET)
    {
        return NULL;
    }
    if(soap_header->soap_version == AXIOM_SOAP11)
    {
        localname = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI;
        nsuri = AXIOM_SOAP11_ATTR_ACTOR;
    }
    if(soap_header->soap_version == AXIOM_SOAP12)
    {
        localname = AXIOM_SOAP12_SOAP_ROLE;
        nsuri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
    }

    qn = axutil_qname_create(env, localname, nsuri, NULL);
    if(!qn)
    {
        return NULL;
    }
    header_om_ele = (axiom_element_t *)axiom_node_get_data_element(soap_header->om_ele_node, env);

    if(header_om_ele)
    {
        first_ele = axiom_element_get_first_element(header_om_ele, env, soap_header->om_ele_node,
            &first_node);
        if(first_node)
        {
            return axiom_children_with_specific_attribute_iterator_create(env, first_node, qn,
                role, AXIS2_TRUE);
        }
    }

    axutil_qname_free(qn, env);

    return iter;

}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_header_set_base_node(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    axiom_node_t * node)
{
    AXIS2_PARAM_CHECK(env->error, node, AXIS2_FAILURE);

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

    soap_header->om_ele_node = node;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
axiom_soap_header_get_base_node(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env)
{
    if(!soap_header->om_ele_node)
    {
        axiom_node_t *parent_node = NULL;
        axiom_element_t *parent_ele = NULL;
        axiom_namespace_t *parent_ns = NULL;
        axiom_element_t *this_ele = NULL;
        axiom_node_t *this_node = NULL;
        axiom_soap_body_t *soap_body = NULL;
        axiom_node_t *body_node = NULL;

        parent_node = axiom_soap_envelope_get_base_node(soap_header->soap_envelope, env);

        if(!parent_node || axiom_node_get_node_type(parent_node, env) != AXIOM_ELEMENT)
        {
            axiom_soap_header_free(soap_header, env);
            return NULL;
        }

        parent_ele = (axiom_element_t *)axiom_node_get_data_element(parent_node, env);
        if(!parent_ele)
        {
            axiom_soap_header_free(soap_header, env);
            return NULL;
        }

        parent_ns = axiom_element_get_namespace(parent_ele, env, parent_node);
        this_ele = axiom_element_create(env, NULL, AXIOM_SOAP_HEADER_LOCAL_NAME, parent_ns,
            &this_node);
        if(!this_ele)
        {
            axiom_soap_header_free(soap_header, env);
            return NULL;
        }

        soap_body = axiom_soap_envelope_get_body(soap_header->soap_envelope, env);
        if(soap_body)
        {
            body_node = axiom_soap_body_get_base_node(soap_body, env);
            axiom_node_insert_sibling_before(body_node, env, this_node);
        }
        else
        {
            axiom_node_add_child(parent_node, env, this_node);
        }
        soap_header->om_ele_node = this_node;
    }

    return soap_header->om_ele_node;
}

/**
 set soap version and get soap version are internal functions

 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_header_get_soap_version(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env)
{
    return soap_header->soap_version;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_header_set_soap_version(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    int soap_version)
{
    soap_header->soap_version = soap_version;
    return AXIS2_SUCCESS;

}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_header_set_header_block(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    struct axiom_soap_header_block * header_block)
{
    axis2_char_t *key = NULL;
    AXIS2_PARAM_CHECK(env->error, header_block, AXIS2_FAILURE);

    key = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 10);

    if(!key)
    {
        return AXIS2_FAILURE;
    }
    sprintf(key, "%d", soap_header->hbnumber++);

    if(soap_header->header_blocks)
    {
        axutil_hash_set(soap_header->header_blocks, key, AXIS2_HASH_KEY_STRING, header_block);
    }
    else
    {
        soap_header->header_blocks = axutil_hash_make(env);
        axutil_hash_set(soap_header->header_blocks, key, AXIS2_HASH_KEY_STRING, header_block);
    }
    if(soap_header->header_block_keys)
    {
        axutil_array_list_add(soap_header->header_block_keys, env, key);
    }
    return AXIS2_SUCCESS;

}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_header_set_builder(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    struct axiom_soap_builder * builder)
{
    AXIS2_PARAM_CHECK(env->error, builder, AXIS2_FAILURE);

    soap_header->soap_builder = builder;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
axiom_soap_header_get_header_blocks_with_namespace_uri(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    const axis2_char_t * ns_uri)
{
    axutil_array_list_t *header_block_list = NULL;
    axutil_hash_index_t *hash_index = NULL;

    axiom_soap_header_block_t *header_block = NULL;

    axiom_node_t *header_block_om_node = NULL;
    axiom_element_t *header_block_om_ele = NULL;

    axiom_namespace_t *ns = NULL;
    axis2_char_t *hb_namespace_uri = NULL;

    int found = 0;
    void *hb = NULL;

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

    if(!(soap_header->header_blocks))
    {
        return NULL;
    }
    header_block_list = axutil_array_list_create(env, 10);
    if(!header_block_list)
    {
        return NULL;
    }
    for(hash_index = axutil_hash_first(soap_header->header_blocks, env); hash_index; hash_index
        = axutil_hash_next(env, hash_index))
    {
        axutil_hash_this(hash_index, NULL, NULL, &hb);
        if(hb)
        {
            header_block = (axiom_soap_header_block_t *)hb;

            header_block_om_node = axiom_soap_header_block_get_base_node(header_block, env);
            if(header_block_om_node)
            {
                header_block_om_ele = (axiom_element_t *)axiom_node_get_data_element(
                    header_block_om_node, env);
                if(header_block_om_ele)
                {
                    ns
                        = axiom_element_get_namespace(header_block_om_ele, env,
                            header_block_om_node);
                    if(ns)
                    {
                        hb_namespace_uri = axiom_namespace_get_uri(ns, env);
                        if(axutil_strcmp(hb_namespace_uri, ns_uri) == 0)
                        {
                            axutil_array_list_add(header_block_list, env, header_block);
                            found++;
                        }
                    }
                }
            }
            hb = NULL;
            header_block = NULL;
            header_block_om_ele = NULL;
            header_block_om_node = NULL;
            ns = NULL;
            hb_namespace_uri = NULL;
        }
    }
    if(found > 0)
    {
        return header_block_list;
    }
    else
    {
        axutil_array_list_free(header_block_list, env);
    }
    return NULL;
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axiom_soap_header_get_all_header_blocks(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env)
{
    return soap_header->header_blocks;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_soap_header_remove_header_block(
    axiom_soap_header_t * soap_header,
    const axutil_env_t * env,
    axutil_qname_t * qname)
{
    axis2_char_t *qn_localname = NULL;
    axis2_char_t *qname_ns = NULL;
    axis2_char_t *qname_prefix = NULL;
    axutil_hash_index_t *hi = NULL;

    AXIS2_PARAM_CHECK(env->error, qname, AXIS2_FAILURE);

    qn_localname = axutil_qname_get_localpart(qname, env);
    qname_ns = axutil_qname_get_uri(qname, env);
    qname_prefix = axutil_qname_get_prefix(qname, env);

    if(!soap_header->header_blocks)
    {
        return AXIS2_FAILURE;
    }
    for(hi = axutil_hash_first(soap_header->header_blocks, env); hi; hi = axutil_hash_next(env, hi))
    {
        const void *key = NULL;
        void *val = NULL;

        axutil_hash_this(hi, &key, NULL, &val);
        if(val)
        {
            axiom_soap_header_block_t *header_block = NULL;
            axiom_element_t *ele = NULL;
            axiom_node_t *node = NULL;

            header_block = (axiom_soap_header_block_t *)val;
            node = axiom_soap_header_block_get_base_node(header_block, env);
            if(node)
            {
                axutil_qname_t *element_qname = NULL;

                ele = (axiom_element_t *)axiom_node_get_data_element(node, env);
                element_qname = axiom_element_get_qname(ele, env, node);
                if(axiom_soap_header_qname_matches(env, element_qname, qname) == AXIS2_TRUE)
                {
                    axiom_node_detach(node, env);
                    /* axiom_node_free_tree(node, env); */
                    axutil_hash_set(soap_header->header_blocks, key, AXIS2_HASH_KEY_STRING, NULL);
                    axiom_soap_header_block_free(header_block, env);
                    axiom_node_free_tree(node, env);
                    break;
                }
            }
        }
    }

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

    return AXIS2_SUCCESS;
}

static axis2_bool_t AXIS2_CALL
axiom_soap_header_qname_matches(
    const axutil_env_t * env,
    axutil_qname_t * element_qname,
    axutil_qname_t * qname_to_match)
{
    int lparts_match = 0;
    int uris_match = 0;
    axis2_char_t *ele_lpart = NULL;
    axis2_char_t *match_lpart = NULL;
    axis2_char_t *ele_nsuri = NULL;
    axis2_char_t *match_nsuri = NULL;

    if(!(qname_to_match))
    {
        return AXIS2_TRUE;
    }
    if(qname_to_match)
    {
        match_lpart = axutil_qname_get_localpart(qname_to_match, env);
        match_nsuri = axutil_qname_get_uri(qname_to_match, env);
    }
    if(element_qname)
    {
        ele_lpart = axutil_qname_get_localpart(element_qname, env);
        ele_nsuri = axutil_qname_get_uri(element_qname, env);
    }

    lparts_match = (!match_lpart || (axutil_strcmp(match_lpart, "") == 0) || (element_qname
        && (axutil_strcmp(ele_lpart, match_lpart) == 0)));

    uris_match = (!match_nsuri || (axutil_strcmp(match_nsuri, "") == 0) || (element_qname
        && (axutil_strcmp(ele_nsuri, match_nsuri) == 0)));

    return lparts_match && uris_match;
}
