/*
 * 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 <axutil_duration.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <axutil_error.h>
#include <axutil_utils.h>

struct axutil_duration
{
    axis2_bool_t is_negative;
    int years;
    int months;
    int days;
    int hours;
    int mins;
    double secs;
};

AXIS2_EXTERN axutil_duration_t *AXIS2_CALL
axutil_duration_create(
    axutil_env_t *env)
{
    return axutil_duration_create_from_values(env, 0, 0, 0, 0, 0, 0, 0.0);
}

AXIS2_EXTERN axutil_duration_t *AXIS2_CALL
axutil_duration_create_from_values(
    const axutil_env_t *env,
    axis2_bool_t negative,
    int years,
    int months,
    int days,
    int hours,
    int minutes,
    double seconds)
{
    axutil_duration_t *duration = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    duration = (axutil_duration_t *) AXIS2_MALLOC(env->allocator,
            sizeof(axutil_duration_t));
    if (!duration)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }

    duration->is_negative = negative;
    if (years > -1)
    {
        duration->years = years;
    }
    else
    {
        duration->years = 0;
    }
    if (months > -1)
    {
        duration->months = months;
    }
    else
    {
        duration->months = 0;
    }
    if (days > -1)
    {
        duration->days = days;
    }
    else
    {
        duration->days = 0;
    }
    if (hours > -1)
    {
        duration->hours = hours;
    }
    else
    {
        duration->hours = 0;
    }
    if (minutes > -1)
    {
        duration->mins = minutes;
    }
    else
    {
        duration->mins = 0;
    }
    if (seconds >= 0)
    {
        duration->secs = seconds;
    }
    else
    {
        duration->secs = 0.0;
    }
    return duration;
}

AXIS2_EXTERN axutil_duration_t *AXIS2_CALL
axutil_duration_create_from_string(
    const axutil_env_t *env,
    axis2_char_t *duration_str)
{
    axutil_duration_t *duration = NULL;

    duration = (axutil_duration_t *) AXIS2_MALLOC(env->allocator,
        sizeof(axutil_duration_t));
    if (!duration)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
		AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }

    axutil_duration_deserialize_duration(duration, env, duration_str);
    return duration;
}

/***************************Function implementation****************************/

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_free(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

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

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_deserialize_duration(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    const axis2_char_t *duration_str)
{
    const axis2_char_t *cur = duration_str;
    double num;
    int num_type = 0;
    unsigned int seq = 0;
    const char desig[] = { 'Y', 'M', 'D', 'H', 'M', 'S' };

    AXIS2_PARAM_CHECK(env->error, duration, AXIS2_FAILURE);

    duration->is_negative = AXIS2_FALSE;
    duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
    duration->secs = 0;

    if (!duration_str)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM,
            AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    if (*cur == '-')
    {
        duration->is_negative = 1;
        cur++;
    }

    if (*cur++ != 'P')
    {
        duration->is_negative = AXIS2_FALSE;
        duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
        duration->secs = 0;
        
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    if (!*cur)
    {
        duration->is_negative = AXIS2_FALSE;
        duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
        duration->secs = 0;

        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
        return AXIS2_FAILURE;
    }

    while (*cur)
    {
        if (seq >= sizeof(desig))
        {
            duration->is_negative = AXIS2_FALSE;
            duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
            duration->secs = 0;

            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }

        if (*cur == 'T')
        {
            if (!(seq > 3))
            {
                seq = 3;
                cur++;
            }
            else
            {
                duration->is_negative = AXIS2_FALSE;
                duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
                duration->secs = 0;

                AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
                return AXIS2_FAILURE;
            }
        }
        num = 0;

        if ((*cur < '0') || (*cur > '9'))
            num_type = -1;
        else
        {
            num_type = 0;
            while ((*cur >= '0') && (*cur <= '9'))
            {
                num = num * 10 + (*cur - '0');
                cur++;
            }
        }

        if (!num_type && (*cur == '.'))
        {
            double mult = 1;
            cur++;
            if ((*cur < '0') || (*cur > '9'))
                num_type = -1;
            else
                num_type = 1;
            while ((*cur >= '0') && (*cur <= '9'))
            {
                mult /= 10;
                num += (*cur - '0') * mult;
                cur++;
            }
        }

        if ((num_type == -1) || (*cur == 0))
        {
            duration->is_negative = AXIS2_FALSE;
            duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
            duration->secs = 0;

            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
            return AXIS2_FAILURE;
        }

        while (seq < sizeof(desig))
        {
            if (*cur == desig[seq])
            {
                num_type = 0;
                if (seq < (sizeof(desig) - 1))
                {
                    duration->is_negative = AXIS2_FALSE;
                    duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
                    duration->secs = 0;

                    AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE,
                                    AXIS2_FAILURE);
                    return AXIS2_FAILURE;
                }

                switch (seq)
                {
                case 0:
                    duration->years = (int) num;
                    seq++;
                    break;
                case 1:
                    duration->months = (int) num;
                    seq++;
                    break;
                case 2:
                    duration->days = (int) num;
                    seq++;
                    break;
                case 3:
                    duration->hours = (int) num;
                    seq++;
                    break;
                case 4:
                    duration->mins = (int) num;
                    seq++;
                    break;
                case 5:
                    duration->secs = num;
                    seq++;
                    break;
                }
                break;
            }
            if ((++seq == 3) || (seq == 6))
                return AXIS2_SUCCESS;
        }
        cur++;
    }
    return AXIS2_SUCCESS;

}

AXIS2_EXTERN char *AXIS2_CALL
axutil_duration_serialize_duration(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    axis2_char_t *duration_str = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    duration_str = (axis2_char_t *) AXIS2_MALLOC(env->allocator,
                       sizeof(axis2_char_t) * 64);

    if (duration->is_negative == 0)
        sprintf(duration_str, "P%dY%dM%dDT%dH%dM%fS", duration->years,
            duration->months, duration->days, duration->hours,
            duration->mins, duration->secs);
    else
        sprintf(duration_str, "-P%dY%dM%dDT%dH%dM%fS", duration->years,
            duration->months, duration->days, duration->hours,
            duration->mins, duration->secs);

    return duration_str;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_duration(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    axis2_bool_t negative,
    int years,
    int months,
    int days,
    int hours,
    int mins,
    double seconds)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if (years > -1)
        duration->years = years;
    if (months > -1)
        duration->months = months;
    if (days > -1)
        duration->days = days;
    if (hours > -1)
        duration->hours = hours;
    if (mins > -1)
        duration->mins = mins;
    if (seconds >= 0)
        duration->secs = seconds;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_years(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->years;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_years(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    int years)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (years > -1)
    {
        duration->years = years;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_months(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->months;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_months(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    int months)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (months > -1)
    {
        duration->months = months;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_days(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->days;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_days(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    int days)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (days > -1)
    {
        duration->days = days;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_hours(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->hours;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_hours(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    int hours)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (hours > -1)
    {
        duration->hours = hours;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_mins(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->mins;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_mins(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    int mins)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (mins > -1)
    {
        duration->mins = mins;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN double AXIS2_CALL
axutil_duration_get_seconds(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->secs;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_seconds(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    double seconds)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    if (seconds >= 0)
    {
        duration->secs = seconds;
    }

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_duration_get_is_negative(
    axutil_duration_t *duration,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    return duration->is_negative;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_is_negative(
    axutil_duration_t *duration,
    const axutil_env_t *env,
    axis2_bool_t is_negative)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
    duration->is_negative = is_negative;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_duration_compare(
    axutil_duration_t *duration_one,
    axutil_duration_t *duration_two,
    axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FALSE);

    if (!duration_one || !duration_two)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM,
            AXIS2_FAILURE);
        return AXIS2_FALSE;
    }

    if (duration_one->is_negative != duration_two->is_negative)
        return AXIS2_FALSE;
    if (duration_one->years != duration_two->years)
        return AXIS2_FALSE;
    if (duration_one->months != duration_two->months)
        return AXIS2_FALSE;
    if (duration_one->days != duration_two->days)
        return AXIS2_FALSE;
    if (duration_one->hours != duration_two->hours)
        return AXIS2_FALSE;
    if (duration_one->mins != duration_two->mins)
        return AXIS2_FALSE;
    if (duration_one->secs != duration_two->secs)
        return AXIS2_FALSE;
    return AXIS2_SUCCESS;
}

