/*
 * 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_properties.h>
#include <axutil_string.h>
#include <axutil_utils.h>

#define MAX_SIZE 1024
#define MAX_ALLOC (MAX_SIZE * 64)

axis2_char_t *
axutil_properties_read(
    FILE *input,
    const axutil_env_t *env);

axis2_char_t *
axutil_properties_read_next(
    axis2_char_t *cur);

axis2_char_t *
axutil_properties_trunk_and_dup(
    axis2_char_t *start,
    axis2_char_t *end,
    const axutil_env_t *env);

struct axutil_properties
{
    axutil_hash_t *prop_hash;
};

AXIS2_EXTERN axutil_properties_t *AXIS2_CALL
axutil_properties_create(
    const axutil_env_t *env)
{
    axutil_properties_t *properties = NULL;

    AXIS2_ENV_CHECK(env, NULL);

    properties = (axutil_properties_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_properties_t));

    if(!properties)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Not enough memory");
        return NULL;
    }
    properties->prop_hash = axutil_hash_make(env);

    return properties;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_properties_free(
    axutil_properties_t *properties,
    const axutil_env_t *env)
{
    axis2_char_t *key = NULL;
    axis2_char_t *value = NULL;
    axutil_hash_index_t *hi = NULL;

    if(properties->prop_hash)
    {
        for(hi = axutil_hash_first(properties->prop_hash, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, (void *)&key, NULL, (void *)&value);
            if(key)
            {
                AXIS2_FREE(env->allocator, key);
            }
            if(value)
            {
                AXIS2_FREE(env->allocator, value);
            }
        }
        axutil_hash_free(properties->prop_hash, env);
    }

    if(properties)
    {
        AXIS2_FREE(env->allocator, properties);
    }
    return;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_properties_get_property(
    axutil_properties_t *properties,
    const axutil_env_t *env,
    axis2_char_t *key)
{
    AXIS2_PARAM_CHECK(env->error, key, NULL);

    return axutil_hash_get(properties->prop_hash, key, AXIS2_HASH_KEY_STRING);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_properties_set_property(
    axutil_properties_t *properties,
    const axutil_env_t *env,
    axis2_char_t *key,
    axis2_char_t *value)
{
    axis2_char_t *old = NULL;
    AXIS2_PARAM_CHECK(env->error, key, AXIS2_FAILURE);

    old = axutil_properties_get_property(properties, env, key);
    if(old)
    {
        AXIS2_FREE(env->allocator, old);
        axutil_hash_set(properties->prop_hash, key, AXIS2_HASH_KEY_STRING,
            axutil_strdup(env, value));
        return AXIS2_SUCCESS;
    }
    axutil_hash_set(properties->prop_hash, axutil_strdup(env, key), AXIS2_HASH_KEY_STRING,
        axutil_strdup(env, value));
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
axutil_properties_get_all(
    axutil_properties_t *properties,
    const axutil_env_t *env)
{
    return properties->prop_hash;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_properties_store(
    axutil_properties_t *properties,
    const axutil_env_t *env,
    FILE *output)
{
    axutil_hash_index_t *hi = NULL;
    axis2_char_t *key = NULL;
    axis2_char_t *value = NULL;

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

    if(properties->prop_hash)
    {
        for(hi = axutil_hash_first(properties->prop_hash, env); hi; hi = axutil_hash_next(env, hi))
        {
            axutil_hash_this(hi, (void *)&key, NULL, (void *)&value);
            if(key)
            {
                if(!value)
                {
                    value = axutil_strdup(env, "");
                }
                fprintf(output, "%s=%s\n", key, value);
            }
        }
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_properties_load(
    axutil_properties_t *properties,
    const axutil_env_t *env,
    axis2_char_t *input_filename)
{
    FILE *input = NULL;
    axis2_char_t *cur = NULL;
    axis2_char_t *tag = NULL;
    const int LINE_STARTED = -1;
    const int LINE_MIDWAY = 0;
    const int EQUAL_FOUND = 1;
    const int LINE_HALFWAY = 2;
    int status = LINE_STARTED;

    axis2_char_t *key = NULL;
    axutil_hash_t *prop_hash = NULL;
    axis2_char_t *buffer = NULL;
    axis2_char_t loginfo[1024];

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

    prop_hash = properties->prop_hash;

    input = fopen(input_filename, "r+");
    if(!input)
    {
        return AXIS2_FAILURE;
    }
    buffer = axutil_properties_read(input, env);

    if(!buffer)
    {
        sprintf(loginfo, "error in reading file\n");
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, loginfo);
        AXIS2_FREE(env->allocator, buffer);
        return AXIS2_FAILURE;
    }

    for(cur = axutil_properties_read_next(buffer); *cur; cur = axutil_properties_read_next(++cur))
    {
        if(*cur == '\r')
        {
            *cur = '\0';
        }
        else if(*cur != '\0' && *cur != '\n' && status == LINE_STARTED)
        {
            tag = cur;
            status = LINE_MIDWAY;
        }
        /* equal found just create a property */
        else if(*cur == '=' && status == LINE_MIDWAY)
        {
            *cur = '\0';
            if(status != LINE_MIDWAY)
            {
                sprintf(loginfo, "equal apear in wrong place around %s\n", tag);
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, loginfo);
                AXIS2_FREE(env->allocator, buffer);
                return AXIS2_FAILURE;
            }
            status = EQUAL_FOUND;
            key = axutil_properties_trunk_and_dup(tag, cur, env);
        }
        /* right next to the equal found */
        else if(status == EQUAL_FOUND)
        {
            tag = cur;
            status = LINE_HALFWAY;
        }

        else if(*cur == '\n')
        {
            *cur = '\0';
            if(status == LINE_HALFWAY)
            {
                tag = axutil_properties_trunk_and_dup(tag, cur, env);
                axutil_hash_set(prop_hash, key, AXIS2_HASH_KEY_STRING, tag);
            }
            status = LINE_STARTED;
        }
    }
    if(status == LINE_HALFWAY)
    {
        *cur = '\0';
        tag = axutil_properties_trunk_and_dup(tag, cur, env);
        axutil_hash_set(prop_hash, key, AXIS2_HASH_KEY_STRING, tag);
        status = LINE_STARTED;
    }
    if(status != LINE_STARTED)
    {
        sprintf(loginfo, "error parsing properties\n");
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, loginfo);
        AXIS2_FREE(env->allocator, buffer);
        return AXIS2_FAILURE;
    }
    if(input)
    {
        fclose(input);
    }
    AXIS2_FREE(env->allocator, buffer);
    return AXIS2_SUCCESS;
}

axis2_char_t *
axutil_properties_read_next(
    axis2_char_t *cur)
{
    /* ignore comment */
    if(*cur == '#')
    {
        for(; *cur != '\n' && *cur != '\0'; cur++)
            ;
    }
    /* check '\\''\n' case */
    if(*cur == '\\' && *(cur + 1) == '\n')
    {
        /* ignore two axis2_char_ts */
        *(cur++) = ' ';
        *(cur++) = ' ';
    }
    return cur;
}

axis2_char_t *
axutil_properties_trunk_and_dup(
    axis2_char_t *start,
    axis2_char_t *end,
    const axutil_env_t *env)
{
    for(; *start == ' '; start++)
        ; /* remove front spaces */
    for(end--; *end == ' '; end--)
        ; /* remove rear spaces */
    *(++end) = '\0';
    start = (axis2_char_t *)axutil_strdup(env, start);
    return start;
}

axis2_char_t *
axutil_properties_read(
    FILE *input,
    const axutil_env_t *env)
{
    size_t nread = 0;
    axis2_char_t *out_stream = NULL;
    size_t ncount = 0;
    size_t curr_alloc = MAX_SIZE * 2;
    size_t total_alloc = curr_alloc;

    out_stream = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * curr_alloc);
    if(!out_stream)
    {
        return NULL;
    }

    do
    {
        nread = fread(out_stream + ncount, sizeof(axis2_char_t), MAX_SIZE, input);
        ncount += nread;

        if(ncount + MAX_SIZE > total_alloc)
        {
            axis2_char_t *new_stream = NULL;
            if(curr_alloc < MAX_ALLOC)
            {
                curr_alloc *= 2;
            }

            total_alloc += curr_alloc;
            new_stream = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * total_alloc);
            if(!new_stream)
            {
                if(out_stream)
                {
                    AXIS2_FREE(env->allocator, out_stream);
                }
                return NULL;
            }

            memcpy(new_stream, out_stream, sizeof(axis2_char_t) * ncount);
            if(out_stream)
            {
                AXIS2_FREE(env->allocator, out_stream);
            }
            out_stream = new_stream;
        }
    }
    while(nread == MAX_SIZE);

    out_stream[ncount] = '\0';
    return out_stream;
}
