/*
 * 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)
    {
        AXIS2_FREE(env->allocator, expr->expr_str);
        AXIS2_FREE(env->allocator, 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)
        {
            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)
        {
            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;
    }
}

