/*
 * 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 <axis2_const.h>
#include <axis2_phase_rule.h>
#include <axutil_string.h>

struct axis2_phase_rule
{

    /** name of phase or handler before */
    axis2_char_t *before;

    /** name of phase or handler after */
    axis2_char_t *after;

    /** phase name */
    axis2_char_t *name;

    /** Is this first in phase? */
    axis2_bool_t first;

    /** Is this last in phase? */
    axis2_bool_t last;

};

AXIS2_EXTERN axis2_phase_rule_t *AXIS2_CALL
axis2_phase_rule_create(
    const axutil_env_t * env,
    const axis2_char_t * name)
{
    axis2_phase_rule_t *phase_rule = NULL;

    phase_rule = AXIS2_MALLOC(env->allocator, sizeof(axis2_phase_rule_t));
    if(!phase_rule)
    {
        AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY);
        AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
        return NULL;
    }

    phase_rule->before = NULL;
    phase_rule->after = NULL;
    phase_rule->name = NULL;
    phase_rule->first = AXIS2_FALSE;
    phase_rule->last = AXIS2_FALSE;

    if(name)
    {
        phase_rule->name = axutil_strdup(env, name);
    }

    return phase_rule;
}

const axis2_char_t *AXIS2_CALL
axis2_phase_rule_get_before(
    const axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    return phase_rule->before;
}

axis2_status_t AXIS2_CALL
axis2_phase_rule_set_before(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env,
    const axis2_char_t * before)
{
    if(phase_rule->before)
    {
        AXIS2_FREE(env->allocator, phase_rule->before);
    }

    if(before)
    {
        phase_rule->before = axutil_strdup(env, before);
        if(!phase_rule->before)
        {
            AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY);
            AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    return AXIS2_SUCCESS;
}

const axis2_char_t *AXIS2_CALL
axis2_phase_rule_get_after(
    const axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    return phase_rule->after;
}

axis2_status_t AXIS2_CALL
axis2_phase_rule_set_after(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env,
    const axis2_char_t * after)
{
    if(phase_rule->after)
    {
        AXIS2_FREE(env->allocator, phase_rule->after);
    }

    if(after)
    {
        phase_rule->after = axutil_strdup(env, after);
        if(!phase_rule->after)
        {
            AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY);
            AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    return AXIS2_SUCCESS;
}

const axis2_char_t *AXIS2_CALL
axis2_phase_rule_get_name(
    const axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    return phase_rule->name;
}

axis2_status_t AXIS2_CALL
axis2_phase_rule_set_name(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env,
    const axis2_char_t * name)
{
    if(phase_rule->name)
    {
        AXIS2_FREE(env->allocator, phase_rule->name);
    }

    if(name)
    {
        phase_rule->name = axutil_strdup(env, name);
        if(!phase_rule->name)
        {
            AXIS2_ERROR_SET_ERROR_NUMBER(env->error, AXIS2_ERROR_NO_MEMORY);
            AXIS2_ERROR_SET_STATUS_CODE(env->error, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }
    }

    return AXIS2_SUCCESS;
}

axis2_bool_t AXIS2_CALL
axis2_phase_rule_is_first(
    const axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    return phase_rule->first;
}

axis2_status_t AXIS2_CALL
axis2_phase_rule_set_first(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env,
    axis2_bool_t first)
{
    phase_rule->first = first;
    return AXIS2_SUCCESS;
}

axis2_bool_t AXIS2_CALL
axis2_phase_rule_is_last(
    const axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    return phase_rule->last;
}

axis2_status_t AXIS2_CALL
axis2_phase_rule_set_last(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env,
    axis2_bool_t last)
{
    phase_rule->last = last;
    return AXIS2_SUCCESS;
}

void AXIS2_CALL
axis2_phase_rule_free(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    if(phase_rule->before)
    {
        AXIS2_FREE(env->allocator, phase_rule->before);
    }

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

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

    AXIS2_FREE(env->allocator, phase_rule);

    return;
}

axis2_phase_rule_t *AXIS2_CALL
axis2_phase_rule_clone(
    axis2_phase_rule_t * phase_rule,
    const axutil_env_t * env)
{
    axis2_phase_rule_t *phase_rule_new = NULL;

    phase_rule_new = axis2_phase_rule_create(env, NULL);
    if(!phase_rule_new)
        return NULL;

    axis2_phase_rule_set_before(phase_rule_new, env, axis2_phase_rule_get_before(phase_rule, env));

    axis2_phase_rule_set_after(phase_rule_new, env, axis2_phase_rule_get_after(phase_rule, env));

    axis2_phase_rule_set_name(phase_rule_new, env, axis2_phase_rule_get_name(phase_rule, env));

    axis2_phase_rule_set_first(phase_rule_new, env, axis2_phase_rule_is_first(phase_rule, env));

    axis2_phase_rule_set_last(phase_rule_new, env, axis2_phase_rule_is_last(phase_rule, env));

    return phase_rule_new;
}

