/*
 * 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 <neethi_engine.h>
#include <neethi_assertion_builder.h>

/*Private functions*/

neethi_all_t *AXIS2_CALL get_operator_all(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element);

neethi_exactlyone_t *AXIS2_CALL get_operator_exactlyone(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element);

neethi_reference_t *AXIS2_CALL get_operator_reference(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element);

neethi_policy_t *AXIS2_CALL get_operator_neethi_policy(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element);

axis2_status_t AXIS2_CALL process_operation_element(
        const axutil_env_t *env,
        neethi_operator_t *neethi_operator,
        axiom_node_t *node,
        axiom_element_t *element);

axis2_status_t AXIS2_CALL neethi_engine_add_policy_component(
        const axutil_env_t *env,
        neethi_operator_t *container_operator,
        neethi_operator_t *component);

axis2_bool_t AXIS2_CALL
operator_is_empty(
    neethi_operator_t *operator,
    const axutil_env_t *env);

neethi_exactlyone_t *AXIS2_CALL
compute_resultant_component(
    axutil_array_list_t *normalized_inner_components,
    neethi_operator_type_t type,
    const axutil_env_t *env);

axutil_array_list_t *AXIS2_CALL
operator_get_components(
    neethi_operator_t *operator,
    const axutil_env_t *env);

neethi_exactlyone_t *AXIS2_CALL
normalize_operator(
    neethi_operator_t *operator,
    neethi_registry_t *registry,
    axis2_bool_t deep,
    const axutil_env_t *env);

neethi_exactlyone_t *AXIS2_CALL
get_cross_product(
    neethi_exactlyone_t *exactlyone1,
    neethi_exactlyone_t *exactlyone2,
    const axutil_env_t *env);



/*Implementations*/

/*This is the function which is called from outside*/

AXIS2_EXTERN neethi_policy_t *AXIS2_CALL
neethi_engine_get_policy(
    const axutil_env_t *env,
    axiom_node_t *node,
    axiom_element_t *element)
{

    return get_operator_neethi_policy(env, node, element);    

}

neethi_all_t *AXIS2_CALL get_operator_all(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element)
{
    neethi_all_t *all = NULL;
    neethi_operator_t *neethi_operator = NULL;
    axis2_status_t status = AXIS2_SUCCESS;
    all = neethi_all_create(env);

    if(!all)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    neethi_operator = neethi_operator_create(env);
    if(!neethi_operator)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }        
    neethi_operator_set_value(neethi_operator, env, all, OPERATOR_TYPE_ALL);
    
    status = process_operation_element(env, neethi_operator, node, element);
    
    neethi_operator_set_value_null(neethi_operator, env);
    neethi_operator_free(neethi_operator, env);
    neethi_operator = NULL;

    if(status != AXIS2_SUCCESS)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_ALL_CREATION_FAILED, 
                AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "[neethi] All creation failed");
        neethi_all_free(all, env);
        all = NULL;
        return NULL;
    }
    return all;
}   

neethi_exactlyone_t *AXIS2_CALL get_operator_exactlyone(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element)
{
    neethi_exactlyone_t *exactlyone = NULL;
    neethi_operator_t *neethi_operator = NULL;
    axis2_status_t status = AXIS2_SUCCESS;

    exactlyone = neethi_exactlyone_create(env);

    if(!exactlyone)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    neethi_operator = neethi_operator_create(env);
    if(!neethi_operator)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }        
    neethi_operator_set_value(neethi_operator, env, exactlyone, 
            OPERATOR_TYPE_EXACTLYONE);
    status = process_operation_element(env, neethi_operator, node, element);

    neethi_operator_set_value_null(neethi_operator, env);
    neethi_operator_free(neethi_operator, env);
    neethi_operator = NULL;

    if(status != AXIS2_SUCCESS)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_EXACTLYONE_CREATION_FAILED,
                AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "[neethi] Exactlyone creation failed.");
        neethi_exactlyone_free(exactlyone, env);
        exactlyone = NULL;
        return NULL;
    }
    
    return exactlyone;
}

neethi_reference_t *AXIS2_CALL get_operator_reference(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element)
{
    neethi_reference_t *reference = NULL;
    axutil_qname_t *qname = NULL;
    axis2_char_t * attribute_value = NULL;

    reference = neethi_reference_create(env);

    if(!reference)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    qname = axutil_qname_create(env, NEETHI_URI, NULL, NULL);

    if(!qname)
    {
        return NULL;
    }

    attribute_value = axiom_element_get_attribute_value(element, env, qname);
    if(attribute_value)
    {
        neethi_reference_set_uri(reference, env, attribute_value);
    }    
    return reference;
}



neethi_policy_t *AXIS2_CALL get_operator_neethi_policy(
        const axutil_env_t *env,
        axiom_node_t *node,
        axiom_element_t *element)
{
    neethi_policy_t *neethi_policy = NULL;
    neethi_operator_t *neethi_operator = NULL;
    axis2_status_t status = AXIS2_SUCCESS;

    neethi_policy = neethi_policy_create(env);

    if(!neethi_policy)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    neethi_operator = neethi_operator_create(env);
    if(!neethi_operator)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }        
    neethi_operator_set_value(neethi_operator, env, neethi_policy, OPERATOR_TYPE_POLICY);
    status = process_operation_element(env, neethi_operator, node, element);

    neethi_operator_set_value_null(neethi_operator, env);
    neethi_operator_free(neethi_operator, env);
    neethi_operator = NULL;

    if(status != AXIS2_SUCCESS)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_POLICY_CREATION_FAILED,
                AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "[neethi] Policy creation failed.");
        neethi_policy_free(neethi_policy, env);
        neethi_policy = NULL;
        return NULL;
    }
    return neethi_policy;
}


axis2_status_t AXIS2_CALL process_operation_element(
        const axutil_env_t *env,
        neethi_operator_t *neethi_operator,
        axiom_node_t *node,
        axiom_element_t *element)
{

    neethi_operator_type_t type;
    axiom_element_t *child_element = NULL;
    axiom_node_t *child_node = NULL;
    axiom_children_iterator_t *children_iter = NULL;
    void *value = NULL;

    type = neethi_operator_get_type(neethi_operator, env);
    value = neethi_operator_get_value(neethi_operator, env);
    if(type == OPERATOR_TYPE_POLICY)
    {
        /*Adding attribute values to the hashmap logic
         *comes here.Following is a little hack until we implement attribute
         hash map logic.*/
        
        axis2_char_t *id = NULL;
        axutil_qname_t *qname = NULL;
        axis2_char_t *name = NULL;

        qname = axutil_qname_create(env, NEETHI_ID, NEETHI_WSU_NS ,NEETHI_WSU_NS_PREFIX);
        if(!qname)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
        id = axiom_element_get_attribute_value(element, env, qname);
        axutil_qname_free(qname,env);
        qname = NULL;

        qname = axutil_qname_create(env, NEETHI_NAME, NULL, NULL); 
        if(!qname)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
        name = axiom_element_get_attribute_value(element, env, qname);
        axutil_qname_free(qname,env);
        qname = NULL;
        
        if(id)
        {
            neethi_policy_set_id((neethi_policy_t *)value, env, id);
        }                      
        if(name)
        {
            neethi_policy_set_name((neethi_policy_t *)value, env, name);
        }
    }
        
    children_iter = axiom_element_get_children(element, env, node);
    if(children_iter)
    {
        while(axiom_children_iterator_has_next(children_iter, env))
        {
            child_node = axiom_children_iterator_next(children_iter, env);
            if(child_node)
            {
                if(axiom_node_get_node_type(child_node , env) == AXIOM_ELEMENT)
                {    
                    child_element = (axiom_element_t*)axiom_node_get_data_element(child_node, env);
                    if(child_element)
                    {
                        axiom_namespace_t *namespace = NULL;
                        axis2_char_t *uri = NULL;
                        axis2_char_t *local_name = NULL;
                        neethi_operator_t *operator = NULL;
                        local_name = axiom_element_get_localname(child_element,env);

                        namespace = axiom_element_get_namespace(child_element, env, child_node);
                        if(!namespace)
                        {
                            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_ELEMENT_WITH_NO_NAMESPACE, 
                                 AXIS2_FAILURE); 
                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[neethi] Element with no namespace");
                            return AXIS2_FAILURE;
                        }                            
                        uri = axiom_namespace_get_uri(namespace, env);
                        if(!uri)
                        {
                            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_EMPTY_NAMESPACE_URI, 
                                AXIS2_FAILURE); 
                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[neethi] Invalid Empty namespace uri.");
                            return AXIS2_FAILURE;
                        }
                        if(axutil_strcmp(uri, NEETHI_NAMESPACE)==0)
                        {                            
                            if(axutil_strcmp(local_name, NEETHI_POLICY)==0)
                            {
                                neethi_policy_t *neethi_policy = NULL;
                                neethi_policy = get_operator_neethi_policy(env, child_node, child_element);
                                if(neethi_policy)
                                {
                                    operator = neethi_operator_create(env);
                                    neethi_operator_set_value(operator, env, neethi_policy, OPERATOR_TYPE_POLICY);
                                    neethi_engine_add_policy_component(env, neethi_operator, operator);
                                }
                                else
                                {
                                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_POLICY_CREATION_FAILED_FROM_ELEMENT, 
                                        AXIS2_FAILURE);
                                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[neethi] Policy creation failed from element.");
                                    return AXIS2_FAILURE;
                                }
                            }
                            else if(axutil_strcmp(local_name, NEETHI_ALL)==0)
                            {
                                neethi_all_t *all = NULL;
                                all = get_operator_all(env, child_node, child_element);
                                if(all)
                                {
                                    operator = neethi_operator_create(env);
                                    neethi_operator_set_value(operator, env, all, OPERATOR_TYPE_ALL);
                                    neethi_engine_add_policy_component(env, neethi_operator, operator);
                                }
                                else
                                {
                                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_ALL_CREATION_FAILED_FROM_ELEMENT, 
                                        AXIS2_FAILURE);
                                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[neethi] All creation failed from element.");
                                    return AXIS2_FAILURE;
                                }
                            }
                            else if(axutil_strcmp(local_name, NEETHI_EXACTLYONE)==0)
                            {
                                neethi_exactlyone_t *exactlyone = NULL;
                                exactlyone = get_operator_exactlyone(env, child_node, child_element);
                                if(exactlyone)
                                {
                                    operator = neethi_operator_create(env);
                                    neethi_operator_set_value(operator, env, exactlyone, OPERATOR_TYPE_EXACTLYONE);
                                    neethi_engine_add_policy_component(env, neethi_operator, operator);
                                }
                                else
                                {
                                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_EXACTLYONE_CREATION_FAILED_FROM_ELEMENT,
                                        AXIS2_FAILURE);
                                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[neethi] Exactlyone creation failed from element.");
                                    return AXIS2_FAILURE;
                                }    
                            }
                            else if(axutil_strcmp(local_name, NEETHI_REFERENCE)==0)
                            {
                                neethi_reference_t *reference = NULL;
                                reference = get_operator_reference(env, child_node, child_element);
                                if(reference)
                                {
                                    operator = neethi_operator_create(env);
                                    neethi_operator_set_value(operator, env, reference, OPERATOR_TYPE_REFERENCE);
                                    neethi_engine_add_policy_component(env, neethi_operator, operator);
                                }
                                else
                                {
                                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_REFERENCE_CREATION_FAILED_FROM_ELEMENT,
                                        AXIS2_FAILURE);
                                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[neethi] Reference cretion failed from element.");
                                    return AXIS2_FAILURE;
                                }
                            }
                        }                            
                        else
                        {                            
                            neethi_assertion_t *assertion = NULL;
                            assertion = neethi_assertion_builder_build(env, child_node, child_element);
                            if(assertion)
                            {    
                                operator = neethi_operator_create(env);
                                neethi_operator_set_value(operator, env, assertion, OPERATOR_TYPE_ASSERTION);
                                neethi_engine_add_policy_component(env, neethi_operator, operator);
                            }
                            else
                            {
                                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_ASSERTION_CREATION_FAILED_FROM_ELEMENT,
                                        AXIS2_FAILURE);
                                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[neethi] Assertion creation failed from element.");
                                return AXIS2_FAILURE;
                            }
                        }                            
                    }
                }
            }
        }
        return AXIS2_SUCCESS;
    }
    else return AXIS2_FAILURE;        
}


axis2_status_t AXIS2_CALL 
neethi_engine_add_policy_component(
    const axutil_env_t *env,
    neethi_operator_t *container_operator,
    neethi_operator_t *component)
{

    neethi_operator_type_t type;
    void *value = NULL;
    neethi_policy_t *neethi_policy = NULL;
    neethi_exactlyone_t *exactlyone = NULL;
    neethi_all_t *all = NULL;
    neethi_assertion_t *assertion = NULL;

    type = neethi_operator_get_type(container_operator, env);
    value = neethi_operator_get_value(container_operator, env);        
    
    if(value)
    {
        switch(type)
        {
            case OPERATOR_TYPE_POLICY:
                neethi_policy = (neethi_policy_t *)value;
                neethi_policy_add_operator(neethi_policy, env, component);   
                break;

            case OPERATOR_TYPE_ALL:
                all = (neethi_all_t *)value;
                neethi_all_add_operator(all, env, component);
                break;

            case OPERATOR_TYPE_EXACTLYONE:
                exactlyone = (neethi_exactlyone_t *)value;
                neethi_exactlyone_add_operator(exactlyone, env, component);
                break;

            case OPERATOR_TYPE_UNKNOWN:
                return AXIS2_FAILURE;
                break;

            case OPERATOR_TYPE_ASSERTION:
                assertion = (neethi_assertion_t *)value;
                neethi_assertion_add_operator(assertion, env, component);
                break;

            case OPERATOR_TYPE_REFERENCE:
                break;
        }
        return AXIS2_SUCCESS;
    }
    else return AXIS2_FAILURE;
}

/***************************************/
/*This function is only for testing*
 *Remove it later*/
void check_neethi_policy(neethi_policy_t *neethi_policy , const axutil_env_t *env)
{
    axutil_array_list_t *list = NULL;
    neethi_operator_t *op = NULL;
    neethi_operator_type_t type;

    list = neethi_policy_get_policy_components(neethi_policy,env);

    if(axutil_array_list_size(list,env)>1)
    {
        /*printf("Error with Normalized neethi_policy\n");*/
        return;
    }        
    op = (neethi_operator_t *)axutil_array_list_get(list,env,0);
    type = neethi_operator_get_type(op,env);
    if(type == OPERATOR_TYPE_EXACTLYONE)
    {
        void *value = neethi_operator_get_value(op,env);
        if(value)
        {
            /*printf("Check is ok\n");*/
            return;
        }          
    }
    else 
    {
        /*printf("Not properly normalized\n");*/
        return;
    }        
}    

/************************************************/

AXIS2_EXTERN neethi_policy_t *AXIS2_CALL
neethi_engine_get_normalize(const axutil_env_t *env,
        axis2_bool_t deep,
        neethi_policy_t *neethi_policy)
{
    return neethi_engine_normalize(env, neethi_policy, NULL, deep);
}


AXIS2_EXTERN neethi_policy_t *AXIS2_CALL
neethi_engine_normalize(const axutil_env_t *env,
    neethi_policy_t *neethi_policy,
    neethi_registry_t *registry,
    axis2_bool_t deep)
{
    neethi_policy_t *resultant_neethi_policy = NULL;
    neethi_operator_t *operator = NULL;
    neethi_operator_t *component = NULL;
    neethi_exactlyone_t *exactlyone = NULL;
    axis2_char_t *policy_name = NULL;
    axis2_char_t *policy_id = NULL;

    resultant_neethi_policy = neethi_policy_create(env);
    if(!resultant_neethi_policy)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    policy_name = neethi_policy_get_name(neethi_policy, env);
    if(policy_name)
    {
        neethi_policy_set_name(resultant_neethi_policy, env, policy_name);
    }        
    policy_id = neethi_policy_get_id(neethi_policy, env);
    if(policy_id)
    {
        neethi_policy_set_id(resultant_neethi_policy, env, policy_id);
    }        

    operator = neethi_operator_create(env);
    if(!operator)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    neethi_operator_set_value(operator, env, neethi_policy, OPERATOR_TYPE_POLICY);

    exactlyone = normalize_operator(operator, registry, deep, env);

    neethi_operator_set_value_null(operator, env);
    neethi_operator_free(operator, env);
    operator = NULL;
   
    if(exactlyone)
    {
        component = neethi_operator_create(env);
        neethi_operator_set_value(component, env, exactlyone, OPERATOR_TYPE_EXACTLYONE);
        neethi_policy_add_operator(resultant_neethi_policy, env, component);
        
        /*check_neethi_policy(resultant_neethi_policy,env);*/
        return resultant_neethi_policy;
    }        
    else
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_NORMALIZATION_FAILED, 
            AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "[neethi] Normalization failed.");
        return NULL;
    }
}

AXIS2_EXTERN neethi_policy_t *AXIS2_CALL
neethi_engine_merge(const axutil_env_t *env,
    neethi_policy_t *neethi_policy1,
    neethi_policy_t *neethi_policy2)
{

    neethi_exactlyone_t *exactlyone1 = NULL;
    neethi_exactlyone_t *exactlyone2 = NULL;
    neethi_exactlyone_t *exactlyone = NULL;
    neethi_policy_t *neethi_policy = NULL;
    neethi_operator_t *component = NULL;

    exactlyone1 = neethi_policy_get_exactlyone(neethi_policy1, env);
    exactlyone2 = neethi_policy_get_exactlyone(neethi_policy2, env);    

    if(!exactlyone1 || !exactlyone2)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_WRONG_INPUT_FOR_MERGE, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "[neethi] Wrong input for merge.");
        return NULL;
    }
    exactlyone = get_cross_product(exactlyone1, exactlyone2, env);
    if(exactlyone)
    {
        neethi_policy = neethi_policy_create(env);
        component = neethi_operator_create(env);
        if(!neethi_policy || !component)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        neethi_operator_set_value(component, env, exactlyone, OPERATOR_TYPE_EXACTLYONE);
        neethi_policy_add_operator(neethi_policy, env, component);
        return neethi_policy;
    }
    else
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_CROSS_PRODUCT_FAILED, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
              "[neethi] Cross product failed.");
        return NULL;
    }
}



axis2_bool_t AXIS2_CALL 
operator_is_empty(
    neethi_operator_t *operator,
    const axutil_env_t *env)
{
    
    neethi_operator_type_t type;
    void *value = NULL;
    neethi_policy_t *neethi_policy = NULL;
    neethi_exactlyone_t *exactlyone = NULL;
    neethi_all_t *all = NULL;
    neethi_assertion_t *assertion = NULL;

    type = neethi_operator_get_type(operator,env);
    value = neethi_operator_get_value(operator,env);

    if(value)
    {
        switch(type)
        {
            case OPERATOR_TYPE_POLICY:
                neethi_policy = (neethi_policy_t *)value;
                return neethi_policy_is_empty(neethi_policy,env);
                break;

            case OPERATOR_TYPE_ALL:
                all = (neethi_all_t *)value;
                return neethi_all_is_empty(all,env);
                break;

            case OPERATOR_TYPE_EXACTLYONE:
                exactlyone = (neethi_exactlyone_t *)value;
                return neethi_exactlyone_is_empty(exactlyone,env);
                break;

            case OPERATOR_TYPE_UNKNOWN:
                return AXIS2_FALSE;
                break;

            case OPERATOR_TYPE_ASSERTION:
                assertion = (neethi_assertion_t *)value;
                return neethi_assertion_is_empty(assertion, env);
                break;

            case OPERATOR_TYPE_REFERENCE:
                break;
                            
        }
        return AXIS2_FALSE;
    }
    else return AXIS2_FALSE;
}

axutil_array_list_t *AXIS2_CALL 
operator_get_components(
    neethi_operator_t *operator,
    const axutil_env_t *env)
{
    
    neethi_operator_type_t type;
    void *value = NULL;
    neethi_policy_t *neethi_policy = NULL;
    neethi_exactlyone_t *exactlyone = NULL;
    neethi_all_t *all = NULL;
    neethi_assertion_t *assertion = NULL;

    type = neethi_operator_get_type(operator,env);
    value = neethi_operator_get_value(operator,env);

    if(value)
    {
        switch(type)
        {
            case OPERATOR_TYPE_POLICY:
                neethi_policy = (neethi_policy_t *)value;
                return neethi_policy_get_policy_components(neethi_policy,env);
                break;

            case OPERATOR_TYPE_ALL:
                all = (neethi_all_t *)value;
                return neethi_all_get_policy_components(all,env);
                break;

            case OPERATOR_TYPE_EXACTLYONE:
                exactlyone = (neethi_exactlyone_t *)value;
                return neethi_exactlyone_get_policy_components(exactlyone,env);
                break;

            case OPERATOR_TYPE_UNKNOWN:
                return NULL;
                break;

            case OPERATOR_TYPE_ASSERTION:
                assertion = (neethi_assertion_t *)value;
                return neethi_assertion_get_policy_components(assertion, env);
                break;

            case OPERATOR_TYPE_REFERENCE:
                break;
        }
    }
    
    return NULL;
}



neethi_exactlyone_t *AXIS2_CALL
normalize_operator(
    neethi_operator_t *operator,
    neethi_registry_t *registry,
    axis2_bool_t deep,
    const axutil_env_t *env)
{
    axutil_array_list_t *child_component_list = NULL;
    neethi_operator_t *child_component = NULL;
    axutil_array_list_t *arraylist = NULL;
    int i = 0;

    neethi_operator_type_t type = neethi_operator_get_type(operator, env);
    
    if(operator_is_empty(operator, env))
    {
        neethi_exactlyone_t *exactlyone = NULL;
        exactlyone = neethi_exactlyone_create(env);
        if(!exactlyone)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
        if(type != OPERATOR_TYPE_EXACTLYONE)
        {
            neethi_all_t *all = NULL;
            neethi_operator_t *component = NULL;
            all = neethi_all_create(env);
            component = neethi_operator_create(env);
            if(!all || !component)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                return NULL;
            }
            neethi_operator_set_value(component, env, all, OPERATOR_TYPE_ALL);
            neethi_exactlyone_add_operator(exactlyone, env, component);
        }                        
        return exactlyone;
    }
    
    child_component_list = axutil_array_list_create(env, 0);     
    arraylist = operator_get_components(operator, env);

    for (i = 0; i < axutil_array_list_size(arraylist, env); i++)
    {
        neethi_operator_type_t component_type;
        child_component = (neethi_operator_t *)axutil_array_list_get(arraylist ,env ,i);
        component_type = neethi_operator_get_type(child_component, env);
        
        if(component_type == OPERATOR_TYPE_ASSERTION)
        {
            /*Assertion normalization part comes here*/
            if(deep)
            {
                /*printf("We still not handling deep normalization of assertions");*/
                return NULL;
            }               
            else
            {
                neethi_exactlyone_t *exactlyone = NULL;
                neethi_all_t *all = NULL;
                neethi_operator_t *op = NULL;

                exactlyone = neethi_exactlyone_create(env);
                all = neethi_all_create(env);
                op = neethi_operator_create(env);

                if(!all || !op || !exactlyone)
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                    return NULL;
                }
                neethi_all_add_operator(all, env, child_component);
                neethi_operator_set_value(op, env, all, OPERATOR_TYPE_ALL);
                neethi_exactlyone_add_operator(exactlyone, env, op);
                axutil_array_list_add(child_component_list, env, exactlyone);
            }                
        }
        else if(component_type == OPERATOR_TYPE_POLICY)
        {
            neethi_policy_t *neethi_policy = NULL;
            neethi_all_t *all = NULL;
            axutil_array_list_t *children = NULL;            
            neethi_operator_t *to_normalize = NULL;
            neethi_exactlyone_t *exactlyone = NULL;

            all = neethi_all_create(env);
            if(!all)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                return NULL;
            }
            neethi_policy = (neethi_policy_t *)neethi_operator_get_value(child_component, env);
            if(neethi_policy)
            {
                children =  neethi_policy_get_policy_components(neethi_policy, env);
                if(children)
                {    
                    neethi_all_add_policy_components(all, children, env);
                    to_normalize = neethi_operator_create(env);
                    if(!to_normalize)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                        return NULL;
                    }
                    neethi_operator_set_value(to_normalize, env, all, OPERATOR_TYPE_ALL);
                    exactlyone = normalize_operator(to_normalize, registry, deep, env);
                    if(exactlyone)
                    {
                        axutil_array_list_add(child_component_list, env, exactlyone);                    
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_NO_CHILDREN_POLICY_COMPONENTS, 
                        AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[neethi] No children policy components");
                    return NULL;
                }
            }
        }

        else if(component_type == OPERATOR_TYPE_REFERENCE)
        {
            neethi_reference_t *policy_ref = NULL;
            axis2_char_t *uri = NULL;
            neethi_policy_t *policy = NULL;
            neethi_all_t *all = NULL;
            axutil_array_list_t *children = NULL;
            neethi_operator_t *to_normalize = NULL;
            neethi_exactlyone_t *exactlyone = NULL;

            policy_ref = (neethi_reference_t *)neethi_operator_get_value(child_component, env);
            uri = neethi_reference_get_uri(policy_ref, env);
            if(!uri)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_URI_NOT_SPECIFIED, 
                     AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[neethi] Uri not specified");
                return NULL;
            }    
            policy = neethi_registry_lookup(registry, env, uri);
            if(!policy)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_NO_ENTRY_FOR_THE_GIVEN_URI, 
                    AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[neethi] No entry for the given uri");
                return NULL;
            }  
            neethi_operator_set_value(child_component, env, policy, OPERATOR_TYPE_POLICY);

            all = neethi_all_create(env);
            if(!all)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                return NULL;
            }

            policy = (neethi_policy_t *)neethi_operator_get_value(child_component, env);
            if(policy)
            {
                children =  neethi_policy_get_policy_components(policy, env);
                if(children)
                {
                    neethi_all_add_policy_components(all, children, env);
                    to_normalize = neethi_operator_create(env);
                    if(!to_normalize)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                        return NULL; 
                    }
                    neethi_operator_set_value(to_normalize, env, all, OPERATOR_TYPE_ALL);
                    exactlyone = normalize_operator(to_normalize, registry, deep, env);
                    if(exactlyone)
                    {
                        axutil_array_list_add(child_component_list, env, exactlyone);
                    }
                }
                else
                {
                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_NO_CHILDREN_POLICY_COMPONENTS, 
                        AXIS2_FAILURE);
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[neethi] No children policy components");
                    return NULL;
                }
            }
        }    
        else
        {
            neethi_exactlyone_t *exactlyone = NULL;
            exactlyone = normalize_operator(child_component, registry, deep, env);
            if(exactlyone)
            {
                axutil_array_list_add(child_component_list, env, exactlyone);
            }
        }
    }

    return compute_resultant_component(child_component_list, type, env);
}


neethi_exactlyone_t *AXIS2_CALL
compute_resultant_component(
    axutil_array_list_t *normalized_inner_components,
    neethi_operator_type_t type,
    const axutil_env_t *env)
{
    neethi_exactlyone_t *exactlyone = NULL;

    if(type == OPERATOR_TYPE_EXACTLYONE)
    {
        int i = 0;
        neethi_exactlyone_t *inner_exactlyone = NULL;
        exactlyone = neethi_exactlyone_create(env);       

        for(i=0; i<axutil_array_list_size(normalized_inner_components, env); i++ )
        {
            inner_exactlyone = (neethi_exactlyone_t *)axutil_array_list_get(normalized_inner_components, env, i);
            if(inner_exactlyone)
            {
                neethi_exactlyone_add_policy_components(exactlyone,
                           neethi_exactlyone_get_policy_components(inner_exactlyone, env), env);
            }
            else
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_EXACTLYONE_NOT_FOUND_IN_NORMALIZED_POLICY, 
                        AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[neethi] Exactlyone not found in normalized policy");
                return NULL;
            }
        }
    }
    else if(type == OPERATOR_TYPE_POLICY ||
                type == OPERATOR_TYPE_ALL)
    {
        if(axutil_array_list_size(normalized_inner_components, env)>1)
        {
            int i = 0;
            exactlyone = (neethi_exactlyone_t *)axutil_array_list_get(normalized_inner_components, env, 0);
            if(!exactlyone)
            {
                AXIS2_ERROR_SET(env->error, 
                                AXIS2_ERROR_NEETHI_EXACTLYONE_NOT_FOUND_IN_NORMALIZED_POLICY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[neethi] Exactlyone not found in normalized policy");
                return NULL;
            }
            if(!neethi_exactlyone_is_empty(exactlyone, env))
            {
                neethi_exactlyone_t *current_exactlyone = NULL;
                i = 1;
                for(i=1; i<axutil_array_list_size(normalized_inner_components, env); i++)
                {
                    current_exactlyone = (neethi_exactlyone_t *)axutil_array_list_get(normalized_inner_components, env, i);
                    if(!current_exactlyone)
                    {
                        AXIS2_ERROR_SET(env->error, 
                                AXIS2_ERROR_NEETHI_EXACTLYONE_NOT_FOUND_IN_NORMALIZED_POLICY, AXIS2_FAILURE);
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[neethi] Exactlyone not found in normalized policy");
                        return NULL;
                    }
                    if(neethi_exactlyone_is_empty(current_exactlyone, env)) 
                    {
                        exactlyone = current_exactlyone;
                        break;    
                    } 
                    else
                    {
                        neethi_exactlyone_t *temp = NULL;
                        neethi_exactlyone_t *temp1 = NULL;
                        temp = exactlyone;
                        temp1 = current_exactlyone;
                        exactlyone = get_cross_product(exactlyone, current_exactlyone, env);
                        neethi_exactlyone_free(temp, env);
                        neethi_exactlyone_free(temp1, env);
                        temp = NULL;
                        temp1 = NULL;
                    }
                }
            }
            else
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_EXACTLYONE_IS_EMPTY, AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[neethi] Exactlyone is Empty");
                return NULL;
            }
        }
        else
        {
            exactlyone = (neethi_exactlyone_t *)axutil_array_list_get(normalized_inner_components, env, 0);   
        }
    }
    axutil_array_list_free(normalized_inner_components, env);
    normalized_inner_components = NULL;
    
    return exactlyone;
}


neethi_exactlyone_t *AXIS2_CALL
get_cross_product(
    neethi_exactlyone_t *exactlyone1,
    neethi_exactlyone_t *exactlyone2,
    const axutil_env_t *env)
{
    neethi_exactlyone_t *cross_product = NULL;
    neethi_all_t *cross_product_all = NULL;
    neethi_all_t *current_all1 = NULL;
    neethi_all_t *current_all2 = NULL;
    axutil_array_list_t *array_list1 = NULL;
    axutil_array_list_t *array_list2 = NULL;
    neethi_operator_t *component = NULL;
    int i = 0;
    int j = 0;

    cross_product = neethi_exactlyone_create(env);
    if(!cross_product)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    array_list1 = neethi_exactlyone_get_policy_components(exactlyone1, env);
    array_list2 = neethi_exactlyone_get_policy_components(exactlyone2, env);

    if(!array_list1 || !array_list2)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_NO_CHILDREN_POLICY_COMPONENTS, 
                AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
               "[neethi] No children policy components");
        return NULL;
    }

    for(i=0; i<axutil_array_list_size(array_list1, env); i++)
    {
        current_all1 = (neethi_all_t *)neethi_operator_get_value(
           (neethi_operator_t *)axutil_array_list_get(array_list1, env, i), env );

        if(!current_all1)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_ALL_NOT_FOUND_WHILE_GETTING_CROSS_PRODUCT , 
                AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                 "[neethi] All not found while getting cross product");
            return NULL;
        }
        
        for(j=0; j<axutil_array_list_size(array_list2,env); j++ )
        {
            current_all2 = (neethi_all_t *)neethi_operator_get_value(
                (neethi_operator_t *)axutil_array_list_get(array_list2, env, j), env);
        
            if(!current_all2)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NEETHI_ALL_NOT_FOUND_WHILE_GETTING_CROSS_PRODUCT ,
                    AXIS2_FAILURE);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[neethi] All not found while getting cross product");
                return NULL;
            }
    
            cross_product_all = neethi_all_create(env);
            if(!cross_product_all)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                return NULL;
            }
            neethi_all_add_policy_components(cross_product_all,
                           neethi_all_get_policy_components(current_all1, env), env);
            
            neethi_all_add_policy_components(cross_product_all,
                           neethi_all_get_policy_components(current_all2, env), env);
            
            component = neethi_operator_create(env);
            if(!component)
            {
                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                return NULL;
            }
            neethi_operator_set_value(component, env, cross_product_all, OPERATOR_TYPE_ALL);
            neethi_exactlyone_add_operator(cross_product, env, component);
        }
    }
    return cross_product;
}

/*These functions are for serializing a policy object*/

AXIS2_EXTERN axiom_node_t *AXIS2_CALL
neethi_engine_serialize(neethi_policy_t *policy,
                   const axutil_env_t *env)
{
    
    return neethi_policy_serialize(policy, NULL, env);
}
