/*
 * 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_xpath.h>
#include "xpath_internals.h"
#include "xpath_internals_parser.h"
#include "xpath_internals_engine.h"
#include "xpath_functions.h"
#include "xpath_streaming.h"

/* Create XPath context */
AXIS2_EXTERN axiom_xpath_context_t * AXIS2_CALL
axiom_xpath_context_create(
    const axutil_env_t *env,
    axiom_node_t * root_node)
{
    axiom_xpath_context_t* context;

    /*HACK: xpath impl requires a dummy root node in order to process properly.*/
    axiom_node_t * dummy_root;
    dummy_root = axiom_node_create(env);
    axiom_node_add_child(dummy_root, env, root_node);

    context = AXIS2_MALLOC(env->allocator,
        sizeof(axiom_xpath_context_t));

    context->env = env;
    context->root_node = dummy_root;
    context->node = dummy_root;
    context->expr = NULL;
    context->attribute = NULL;
    context->namespaces = NULL;
    context->functions = NULL;

    axiom_xpath_register_default_functions_set(context);

    return context;
}

/* Compile XPath expression */
AXIS2_EXTERN axiom_xpath_expression_t * AXIS2_CALL
axiom_xpath_compile_expression(
    const axutil_env_t *env,
    const axis2_char_t* xpath_expr)
{
    axiom_xpath_expression_t* expr;

    expr = AXIS2_MALLOC(env->allocator,
        sizeof(axiom_xpath_expression_t));

    expr->expr_str = axutil_strdup(env, xpath_expr);

    if (axiom_xpath_compile(env, expr) == AXIOM_XPATH_PARSE_ERROR)
    {
        axiom_xpath_free_expression(env, expr);
        return NULL;
    }
    else
    {
        return expr;
    }
}

/* Evaluate compiled XPath expression */
AXIS2_EXTERN axiom_xpath_result_t * AXIS2_CALL
axiom_xpath_evaluate(
    axiom_xpath_context_t *context,
    axiom_xpath_expression_t *xpath_expr)
{
    axiom_xpath_expression_copy(context, xpath_expr);

    context->streaming = AXIS2_FALSE;

    return axiom_xpath_run(context);
}

AXIS2_EXTERN axiom_xpath_result_t * AXIS2_CALL
axiom_xpath_evaluate_streaming(
    axiom_xpath_context_t *context,
    axiom_xpath_expression_t *xpath_expr)
{
    axiom_xpath_result_t *res;

    axiom_xpath_expression_copy(context, xpath_expr);

    if (axiom_xpath_streaming_check(context->env, xpath_expr))
    {
        context->streaming = AXIS2_TRUE;
        return axiom_xpath_run(context);
    }
    else
    {
        res = AXIS2_MALLOC(
            context->env->allocator, sizeof(axiom_xpath_result_t));
        res->nodes = NULL;
        res->flag = AXIOM_XPATH_ERROR_STREAMING_NOT_SUPPORTED;

        return res;
    }
}

AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_register_default_functions_set(
    axiom_xpath_context_t *context)
{
    axiom_xpath_register_function(
        context, "count", axiom_xpath_function_count);
}

AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_register_function(
    axiom_xpath_context_t *context,
    axis2_char_t *name,
    axiom_xpath_function_t func)
{
    if (name && func)
    {
        if (!context->functions)
        {
            context->functions = axutil_hash_make(context->env);
        }

        axutil_hash_set(context->functions, name, AXIS2_HASH_KEY_STRING, (const void *)func);
    }
}

AXIS2_EXTERN axiom_xpath_function_t AXIS2_CALL
axiom_xpath_get_function(
    axiom_xpath_context_t *context,
    axis2_char_t *name)
{
    axiom_xpath_function_t func = NULL;

    if(context->functions)
    {
        func = (axiom_xpath_function_t)axutil_hash_get(context->functions, name, AXIS2_HASH_KEY_STRING);
    }

    return func;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_register_namespace(
    axiom_xpath_context_t *context,
    axiom_namespace_t *ns)
{
    axis2_char_t *prefix = NULL;

    if (!context->namespaces)
    {
        context->namespaces = axutil_hash_make(context->env);
    }

    prefix = axiom_namespace_get_prefix(ns, context->env);

    if (prefix)
    {
        axutil_hash_set(context->namespaces, prefix, AXIS2_HASH_KEY_STRING, (const void *)ns);
    }
}

AXIS2_EXTERN axiom_namespace_t * AXIS2_CALL
axiom_xpath_get_namespace(
    axiom_xpath_context_t *context,
    axis2_char_t *prefix)
{
    axiom_namespace_t *ns = NULL;

    if (context->namespaces)
    {
        ns = (axiom_namespace_t *)axutil_hash_get(context->namespaces, prefix, AXIS2_HASH_KEY_STRING);
    }

    return ns;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_clear_namespaces(
    axiom_xpath_context_t *context)
{
    axutil_hash_index_t *hi;
    void *val;

    if (context->namespaces)
    {
        for (hi = axutil_hash_first(context->namespaces, context->env);
            hi;
            hi = axutil_hash_next(context->env, hi))
        {
            axutil_hash_this(hi, NULL, NULL, &val);
            axiom_namespace_free((axiom_namespace_t *)val, context->env);
        }

        axutil_hash_free(context->namespaces, context->env);
    }

    context->namespaces = NULL;
}

/* Cast to boolean */
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_xpath_cast_node_to_boolean(
    const axutil_env_t *env,
    axiom_xpath_result_node_t * node)
{
    if(node->type == AXIOM_XPATH_TYPE_BOOLEAN)
    {
        return *(axis2_bool_t *)node->value;
    }
    else if(node->type == AXIOM_XPATH_TYPE_NUMBER)
    {
        /* Cannot evaluate as *(double *)(node->value) == 1e-12
         since there might be an precision error */
        if(*(double *)(node->value) > 1e-12 || *(double *)(node->value) < -1e-12)
        {
            return AXIS2_TRUE;
        }
        else
        {
            return AXIS2_FALSE;
        }
    }
    else if(node->value)
    {
        return AXIS2_TRUE;
    }
    else
    {
        return AXIS2_FALSE;
    }
}

/* Cast to double */
AXIS2_EXTERN double AXIS2_CALL
axiom_xpath_cast_node_to_number(
    const axutil_env_t *env,
    axiom_xpath_result_node_t * node)
{
    if (node->type == AXIOM_XPATH_TYPE_BOOLEAN)
    {
        if (*(axis2_bool_t *)(node->value) == AXIS2_TRUE)
        {
            return 1.0;
        }
        else
        {
            return 0.0;
        }
    }
    else if (node->type == AXIOM_XPATH_TYPE_NUMBER)
    {
        return *(double *)node->value;
    }
    else if (node->value)
    {
        return 1.0;
    }
    else
    {
        return 0.0;
    }
}

/* Cast to text */
AXIS2_EXTERN axis2_char_t * AXIS2_CALL
axiom_xpath_cast_node_to_string(
    const axutil_env_t *env,
    axiom_xpath_result_node_t * node)
{
    axiom_element_t *ele;
    axis2_char_t *res;

    if (!node->value)
    {
        return NULL;
    }

    if (node->type == AXIOM_XPATH_TYPE_BOOLEAN)
    {
        if (*(axis2_bool_t *)(node->value) == AXIS2_TRUE)
        {
            return axutil_strdup(env, "true");
        }
        else
        {
            return axutil_strdup(env, "false");
        }
    }
    else if (node->type == AXIOM_XPATH_TYPE_NUMBER)
    {
        /* Allocate 50 bytes */
        res = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 50);

        sprintf(res, "%lf", *(double *)(node->value));

        return res;
    }
    else if (node->type == AXIOM_XPATH_TYPE_TEXT)
    {
        return (axis2_char_t *)node->value;
    }
    else if (node->type == AXIOM_XPATH_TYPE_NODE)
    {
        ele = (axiom_element_t *)axiom_node_get_data_element(
            (axiom_node_t *)(node->value), env);

        if (ele)
        {
            return axiom_element_get_text(
                ele, env, (axiom_node_t *)(node->value));
        }
        else
        {
            return NULL;
        }
    }
    else if (node->type == AXIOM_XPATH_TYPE_ATTRIBUTE)
    {
        return axiom_attribute_get_value(
            (axiom_attribute_t *)(node->value), env);
    }
    else if (node->type == AXIOM_XPATH_TYPE_NAMESPACE)
    {
        return axiom_namespace_get_prefix(
            (axiom_namespace_t *)(node->value), env);
    }

    return NULL;
}

/* Cast to axiom node */
AXIS2_EXTERN axiom_node_t * AXIS2_CALL
axiom_xpath_cast_node2axiom_node(
    const axutil_env_t *env,
    axiom_xpath_result_node_t * node)
{
    if (node->type == AXIOM_XPATH_TYPE_NODE && node->value)
    {
        return (axiom_node_t *)node->value;
    }
    else
    {
        return NULL;
    }
}

/* Free context */
AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_free_context(
    const axutil_env_t *env,
    axiom_xpath_context_t *context)
{
    if (context)
    {
        /* Free the expression if not freed */
        if (context->expr)
        {
            axiom_xpath_free_expression(env, context->expr);

            context->expr = NULL;
        }

        if (context->root_node)
        {
            axiom_node_detach(axiom_node_get_first_child(context->root_node, context->env), context->env);
            axiom_node_free_tree(context->root_node, context->env);
            context->root_node = NULL;
        }

        if (context->functions)
        {
            axutil_hash_free(context->functions, context->env);
            context->functions = NULL;
        }

        if(context->namespaces)
        {
            axiom_xpath_clear_namespaces(context);
            context->namespaces = NULL;
        }

        AXIS2_FREE(env->allocator, context);
    }
}

/* Free expression */
AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_free_expression(
    const axutil_env_t *env,
    axiom_xpath_expression_t * xpath_expr)
{
    if (xpath_expr)
    {
        if (xpath_expr->expr_str)
        {
            AXIS2_FREE(env->allocator, xpath_expr->expr_str);

            xpath_expr->expr_str = NULL;
        }

        if (xpath_expr->operations)
        {
            axiom_xpath_operation_t *op = NULL;
            while(axutil_array_list_size(xpath_expr->operations, env)) {
                op = axutil_array_list_remove(xpath_expr->operations, env, 0);
                if (op->par1)
                    AXIS2_FREE(env->allocator, op->par1);
                if (op->par2)
                    AXIS2_FREE(env->allocator, op->par2);
                AXIS2_FREE(env->allocator, op);
            }
            axutil_array_list_free(xpath_expr->operations, env);
            xpath_expr->operations = NULL;
        }

        AXIS2_FREE(env->allocator, xpath_expr);
    }
}

/* Free result set */
AXIS2_EXTERN void AXIS2_CALL
axiom_xpath_free_result(
    const axutil_env_t *env,
    axiom_xpath_result_t* result)
{
    if (result)
    {
        if (result->nodes)
        {
            axiom_xpath_result_node_t *node = NULL;
            while(axutil_array_list_size(result->nodes, env)) {
                node = axutil_array_list_remove(result->nodes, env, 0);
                AXIS2_FREE(env->allocator, node);
            }
            axutil_array_list_free(result->nodes, env);
        }

        AXIS2_FREE(env->allocator, result);
    }
}

/* Check if the expression can be evaluated on streaming XML */
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axiom_xpath_streaming_check(
    const axutil_env_t *env,
    axiom_xpath_expression_t* expr)
{
    axiom_xpath_streaming_t r = AXIOM_XPATH_CHECK(expr->start);

    if(r == AXIOM_XPATH_STREAMING_NOT_SUPPORTED)
    {
        return AXIS2_FALSE;
    }
    else
    {
        return AXIS2_TRUE;
    }
}

