
/*
 * 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_processing_instruction.h>
#include <axutil_string.h>
#include "axiom_node_internal.h"

struct axiom_processing_instruction
{

    /** processing instruction  target */
    axis2_char_t *target;

    /** processing instruction  value */
    axis2_char_t *value;
};

AXIS2_EXTERN axiom_processing_instruction_t *AXIS2_CALL
axiom_processing_instruction_create(
    const axutil_env_t * env,
    axiom_node_t * parent,
    const axis2_char_t * target,
    const axis2_char_t * value,
    axiom_node_t ** node)
{
    axiom_processing_instruction_t *processing_instruction = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    if (!node || !target || !value)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM,
                        AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
            "Node or target or value is NULL");
        return NULL;
    }

    *node = axiom_node_create(env);

    if (!*node)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }

    processing_instruction =
        (axiom_processing_instruction_t *) AXIS2_MALLOC(env->allocator,
                                                        sizeof
                                                        (axiom_processing_instruction_t));

    if (!processing_instruction)
    {
        AXIS2_FREE(env->allocator, (*node));
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    processing_instruction->value = NULL;

    if (value)
    {
        processing_instruction->value =
            (axis2_char_t *) axutil_strdup(env, value);
        if (!processing_instruction->value)
        {
            AXIS2_FREE(env->allocator, processing_instruction);
            AXIS2_FREE(env->allocator, *node);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
    }

    processing_instruction->target = NULL;

    if (target)
    {
        processing_instruction->target =
            (axis2_char_t *) axutil_strdup(env, target);
        if (!processing_instruction->target)
        {
            AXIS2_FREE(env->allocator, processing_instruction->value);
            AXIS2_FREE(env->allocator, processing_instruction);
            AXIS2_FREE(env->allocator, *node);
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            return NULL;
        }
    }
    axiom_node_set_data_element(*node, env, processing_instruction);
    axiom_node_set_node_type(*node, env, AXIOM_PROCESSING_INSTRUCTION);
    if (parent)
    {
        axiom_node_add_child(parent, env, (*node));
    }

    return processing_instruction;
}

AXIS2_EXTERN void AXIS2_CALL
axiom_processing_instruction_free(
    axiom_processing_instruction_t * om_pi,
    const axutil_env_t * env)
{
    AXIS2_ENV_CHECK(env, void);

    if (om_pi->value)
    {
        AXIS2_FREE(env->allocator, om_pi->value);
        om_pi->value = NULL;
    }

    if (om_pi->target)
    {
        AXIS2_FREE(env->allocator, om_pi->target);
        om_pi->target = NULL;
    }

    AXIS2_FREE(env->allocator, om_pi);
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_processing_instruction_set_value(
    axiom_processing_instruction_t * om_pi,
    const axutil_env_t * env,
    const axis2_char_t * value)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, value, AXIS2_FAILURE);
    om_pi->value = (axis2_char_t *) axutil_strdup(env, value);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_processing_instruction_set_target(
    axiom_processing_instruction_t * om_pi,
    const axutil_env_t * env,
    const axis2_char_t * target)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, target, AXIS2_FAILURE);
    om_pi->target = (axis2_char_t *) axutil_strdup(env, target);
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_processing_instruction_get_value(
    axiom_processing_instruction_t * om_pi,
    const axutil_env_t * env)
{
    return om_pi->value;
}
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axiom_processing_instruction_get_target(
    axiom_processing_instruction_t * om_pi,
    const axutil_env_t * env)
{
    return om_pi->target;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axiom_processing_instruction_serialize(
    axiom_processing_instruction_t * om_pi,
    const axutil_env_t * env,
    axiom_output_t * om_output)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE);

    if (om_pi->target && om_pi->value)
    {
        return axiom_output_write(om_output, env,
                                  AXIOM_PROCESSING_INSTRUCTION,
                                  2, om_pi->target, om_pi->value);
    }
    else if (om_pi->target)
    {
        return axiom_output_write(om_output, env,
                                  AXIOM_PROCESSING_INSTRUCTION,
                                  2, om_pi->target, om_pi->value);
    }
    return AXIS2_FAILURE;
}
