/*
 * 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_string.h>
#include <stdlib.h>
#include <ctype.h>
#include <axutil_utils.h>
#include <axutil_utils_defines.h>
#include <stdarg.h>             /* NULL */

struct axutil_string
{
    axis2_char_t *buffer;
    unsigned int length;
    unsigned int ref_count;
    axis2_bool_t owns_buffer;
};

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axutil_string_create(
    const axutil_env_t *env,
    const axis2_char_t *str)
{
    axutil_string_t *string = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    /* str can't be null */
    if(!str)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "NULL parameter was passed when a non NULL parameter was expected");
        return NULL;
    }

    string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t));
    if(!string)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    /* set properties */
    string->buffer = NULL;
    string->ref_count = 1;
    string->owns_buffer = AXIS2_TRUE;

    string->length = axutil_strlen(str);

    if(string->length < 0)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "NULL parameter was passed when a non NULL parameter was expected");
        axutil_string_free(string, env);
        return NULL;
    }

    string->buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
        * (string->length + 1));
    if(!(string->buffer))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        axutil_string_free(string, env);
        return NULL;
    }
    memcpy(string->buffer, str, string->length + 1);

    return string;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axutil_string_create_assume_ownership(
    const axutil_env_t *env,
    axis2_char_t **str)
{
    axutil_string_t *string = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    /* str can't be null */
    if(!str || !(*str))
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "NULL parameter was passed when a non NULL parameter was expected");
        return NULL;
    }

    string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t));
    if(!string)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    /* set properties */
    string->buffer = *str;
    string->length = axutil_strlen(*str);
    string->ref_count = 1;
    string->owns_buffer = AXIS2_TRUE;

    if(string->length < 0)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "NULL parameter was passed when a non NULL parameter was expected");
        axutil_string_free(string, env);
        return NULL;
    }

    return string;
}

AXIS2_EXTERN axutil_string_t *AXIS2_CALL
axutil_string_create_const(
    const axutil_env_t *env,
    axis2_char_t **str)
{
    axutil_string_t *string = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    /* str can't be null */
    if(!str)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "NULL parameter was passed when a non NULL parameter was expected");

        return NULL;
    }

    string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t));
    if(!string)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    /* set properties */
    string->buffer = *str;
    string->length = axutil_strlen(*str);
    string->ref_count = 1;
    string->owns_buffer = AXIS2_FALSE;

    if(string->length < 0)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "NULL parameter was passed when a non NULL parameter was expected");
        axutil_string_free(string, env);
        return NULL;
    }

    return string;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_string_free(
    struct axutil_string *string,
    const axutil_env_t *env)
{
    if(!string)
    {
        return;
    }

    string->ref_count--;

    if(string->ref_count > 0)
    {
        return;
    }

    if(string->owns_buffer && string->buffer)
    {
        AXIS2_FREE(env->allocator, string->buffer);
    }

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

AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_string_equals(
    const struct axutil_string *string,
    const axutil_env_t * env,
    const struct axutil_string *string1)
{
    if(!string || !string1)
    {
        return AXIS2_FALSE;
    }

    return (string->buffer == string1->buffer);
}

AXIS2_EXTERN struct axutil_string *AXIS2_CALL
axutil_string_clone(
    struct axutil_string *string,
    const axutil_env_t *env)
{
    if(!string)
    {
        return NULL;
    }

    string->ref_count++;

    return string;
}

AXIS2_EXTERN const axis2_char_t *AXIS2_CALL
axutil_string_get_buffer(
    const struct axutil_string *string,
    const axutil_env_t *env)
{
    if(!string)
    {
        return NULL;
    }

    return string->buffer;
}

AXIS2_EXTERN unsigned int AXIS2_CALL
axutil_string_get_length(
    const struct axutil_string *string,
    const axutil_env_t *env)
{
    int error_return = -1;
    if(!string)
    {
        return error_return;
    }

    return string->length;
}

/* END of string struct implementation */

/** this is used to cache lengths in axutil_strcat */
#define MAX_SAVED_LENGTHS  6

AXIS2_EXTERN void *AXIS2_CALL
axutil_strdup(
    const axutil_env_t *env,
    const void *ptr)
{
    if(ptr)
    {
        int len = axutil_strlen(ptr);
        axis2_char_t *str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t)
            * (len + 1));
        if(!str)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
            return NULL;
        }
        memcpy(str, ptr, len + 1);
        return (void *)str;
    }
    else
    {
        return NULL;
    }
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_strmemdup(
    const void *ptr,
    size_t n,
    const axutil_env_t *env)
{
    axis2_char_t *str;

    AXIS2_PARAM_CHECK(env->error, ptr, NULL);

    str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (n + 1));
    if(!str)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    memcpy(str, ptr, n);
    str[n] = '\0';

    return (void *)str;
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_memchr(
    const void *ptr,
    int c,
    size_t n)
{
    const axis2_char_t *cp;

    for(cp = ptr; n > 0; n--, cp++)
    {
        if(*cp == c)
            return (char *)cp; /* Casting away the const here */
    }

    return NULL;
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_strndup(
    const axutil_env_t *env,
    const void *ptr,
    int n)
{
    const axis2_char_t *end;
    axis2_char_t *str;

    AXIS2_PARAM_CHECK(env->error, ptr, NULL);

    end = axutil_memchr(ptr, '\0', n);
    if(end)
        n = (int)(end - (axis2_char_t *)ptr);
    /* We are sure that the difference lies within the int range */
    str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (n + 1));
    if(!str)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    memcpy(str, ptr, n);
    str[n] = '\0';

    return (void *)str;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strcat(
    const axutil_env_t *env,
    ...)
{
    axis2_char_t *cp, *argp, *str;
    size_t saved_lengths[MAX_SAVED_LENGTHS];
    int nargs = 0;
    int str_len = 0;

    /* Pass one --- find length of required string */

    size_t len = 0;
    va_list adummy;

    va_start(adummy, env);

    cp = va_arg(adummy, axis2_char_t *);
    while(cp)
    {
        size_t cplen = strlen(cp);
        if(nargs < MAX_SAVED_LENGTHS)
        {
            saved_lengths[nargs++] = cplen;
        }
        len += cplen;
        cp    = va_arg(adummy, axis2_char_t *);
    }

    va_end(adummy);

    /* Allocate the required string */
    str_len = (int)(sizeof(axis2_char_t) * (len + 1));
    /* We are sure that the difference lies within the int range */
    str = (axis2_char_t *) AXIS2_MALLOC(env->allocator, str_len);
    if (!str)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    cp = str;

    /* Pass two --- copy the argument strings into the result space */

    va_start(adummy, env);

    nargs = 0;
    argp = va_arg(adummy, axis2_char_t *);
    while (argp)
    {
        if (nargs < MAX_SAVED_LENGTHS)
        {
            len = saved_lengths[nargs++];
        }
        else
        {
            len = strlen(argp);
        }

        memcpy(cp, argp, len);
        cp += len;
        argp = va_arg(adummy, axis2_char_t *);
    }

    va_end(adummy);

    /* Return the result string */

    *cp = '\0';
    return str;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_stracat(
    const axutil_env_t *env,
    const axis2_char_t *s1,
    const axis2_char_t *s2)
{
    axis2_char_t *ret = NULL;
    int alloc_len = -1;
    int len1 = 0;
    int len2 = 0;

    if(!s1 && !s2)
    {
        return NULL;
    }
    if(!s1)
    {
        return (axis2_char_t *)axutil_strdup(env, s2);
    }
    if(!s2)
    {
        return (axis2_char_t *)axutil_strdup(env, s1);
    }

    len1 = axutil_strlen(s1);
    len2 = axutil_strlen(s2);
    alloc_len = len1 + len2 + 1;
    ret = (axis2_char_t *)AXIS2_MALLOC(env->allocator, alloc_len * sizeof(axis2_char_t));
    memcpy(ret, s1, len1 * sizeof(axis2_char_t));
    memcpy((ret + len1 * sizeof(axis2_char_t)), s2, len2 * sizeof(axis2_char_t));
    ret[alloc_len * sizeof(axis2_char_t) - sizeof(axis2_char_t)] = '\0';
    return ret;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_strcmp(
    const axis2_char_t *s1,
    const axis2_char_t *s2)
{
    if(s1 && s2)
    {
        return strcmp(s1, s2);
    }
    else
    {
        return -1;
    }
}

AXIS2_EXTERN int AXIS2_CALL
axutil_strncmp(
    const axis2_char_t *s1,
    const axis2_char_t *s2,
    int n)
{
    if(s1 && s2)
    {
        return strncmp(s1, s2, n);
    }
    else
    {
        return -1;
    }
}

AXIS2_EXTERN axis2_ssize_t AXIS2_CALL
axutil_strlen(
    const axis2_char_t *s)
{
    int error_return = -1;
    if(s)
    {
        return (axis2_ssize_t)strlen(s);
        /* We are sure that the difference lies within the axis2_ssize_t range */
    }
    return error_return;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_strcasecmp(
    const axis2_char_t *s1,
    const axis2_char_t *s2)
{
    while(*s1 != '\0' && *s2 != '\0')
    {
        if(*s1 >= 'A' && *s1 <= 'Z' && *s2 >= 'a' && *s2 <= 'z')
        {
            if(*s2 - *s1 - (char)32 != 0)
            {
                return 1;
            }
        }
        else if(*s1 >= 'a' && *s1 <= 'z' && *s2 >= 'A' && *s2 <= 'Z')
        {
            if(*s1 - *s2 - 32 != 0)
            {
                return 1;
            }
        }
        else if(*s1 - *s2 != 0)
        {
            return 1;
        }
        s1++;
        s2++;
    }
    if(*s1 != *s2)
    {
        return 1;
    }

    return 0;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_strncasecmp(
    const axis2_char_t *s1,
    const axis2_char_t *s2,
    const int n)
{
    axis2_char_t *str1 = (axis2_char_t *)s1, *str2 = (axis2_char_t *)s2;
    int i = (int)n;

    while(--i >= 0 && toupper((int)*str1) == toupper((int)*str2++))
    {
        if(toupper((int)*str1++) == '\0')
        {
            return (0);
        }
    }
    return (i < 0 ? 0 : toupper((int)*str1) - toupper((int)*--str2));
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strstr(
    const axis2_char_t *haystack,
    const axis2_char_t *needle)
{
    return strstr(haystack, needle);
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strchr(
    const axis2_char_t *s,
    axis2_char_t ch)
{
    return (axis2_char_t *)strchr(s, ch);
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_rindex(
    const axis2_char_t *_s,
    axis2_char_t _ch)
{
    int i, ilen = axutil_strlen(_s);
    if(ilen < 1)
    {
        return NULL;
    }
    for(i = ilen - 1; i >= 0; i--)
    {
        if(_s[i] == _ch)
        {
            return (axis2_char_t *)(_s + i);
        }
    }
    return NULL;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_replace(
    const axutil_env_t *env,
    axis2_char_t *str,
    int s1,
    int s2)
{
    axis2_char_t *newstr = NULL;
    axis2_char_t *index = NULL;
    if(!str)
    {
        return NULL;
    }

    newstr = axutil_strdup(env, str);
    index = strchr(newstr, s1);
    while(index)
    {
        newstr[index - newstr] = (axis2_char_t)s2;
        /* We are sure that the conversion is safe */
        index = strchr(newstr, s1);
    }
    return newstr;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strltrim(
    const axutil_env_t *env,
    const axis2_char_t *_s,
    const axis2_char_t *_trim)
{
    axis2_char_t *_p = NULL;
    axis2_char_t *ret = NULL;

    if(!_s)
    {
        return NULL;
    }
    _p = (axis2_char_t *)_s;
    if(!_trim)
    {
        _trim = " \t\r\n";
    }

    while(*_p)
    {
        if(!strchr(_trim, *_p))
        {
            ret = (axis2_char_t *)axutil_strdup(env, _p);
            break;
        }
        ++_p;
    }
    return ret;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strrtrim(
    const axutil_env_t *env,
    const axis2_char_t *_in,
    const axis2_char_t *_trim)
{
    axis2_char_t *__tail;
    axis2_char_t *_s = NULL;
    axis2_char_t *ret = NULL;

    if(_in)
    {
        _s = axutil_strdup(env, _in);
    }
    if(!_s)
    {
        return NULL;
    }
    __tail = _s + axutil_strlen(_s);
    if(!_trim)
    {
        _trim = " \t\n\r";
    }
    while(_s < __tail--)
    {
        if(!strchr(_trim, *__tail))
        {
            ret = _s;
            break;
        }
        *__tail = 0;
    }
    if(!ret && _s)
    {
        AXIS2_FREE(env->allocator, _s);
    }
    return ret;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strtrim(
    const axutil_env_t *env,
    const axis2_char_t *_s,
    const axis2_char_t *_trim)
{
    axis2_char_t *_p = NULL;
    axis2_char_t *_q = NULL;

    _p = axutil_strltrim(env, _s, _trim);
    _q = axutil_strrtrim(env, _p, _trim);
    if(_p)
    {
        AXIS2_FREE(env->allocator, _p);
    }
    return _q;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_string_replace(
    axis2_char_t *str,
    axis2_char_t old,
    axis2_char_t new)
{
    axis2_char_t *str_returns = str;
    for(; *str != '\0'; str++)
    {
        if(*str == old)
        {
            *str = new;
        }
    }
    return str_returns;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_string_substring_starting_at(
    axis2_char_t *str,
    int s)
{
    int len;
    int pos_to_shift;

    len = (int)strlen(str);
    /* We are sure that the difference lies within the int range */
    pos_to_shift = len - s + 1;

    if(len <= s)
    {
        return NULL;
    }
    memmove(str, str + s, pos_to_shift);
    return str;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_string_substring_ending_at(
    axis2_char_t *str,
    int e)
{
    axis2_char_t *ptr = NULL;
    int length = 0;

    length = (int)strlen(str);
    /* We are sure that the difference lies within the int range */
    ptr = str;
    if(length <= e)
    {
        return NULL;
    }
    ptr += e;
    *ptr = '\0';
    return str;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_string_tolower(
    axis2_char_t *str)
{
    axis2_char_t *temp_str = NULL;
    for(temp_str = str; *temp_str != '\0'; temp_str++)
    {
        *temp_str = (axis2_char_t)tolower((int)*temp_str);
        /* We are sure that the conversion is safe */
    }
    return str;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_string_toupper(
    axis2_char_t *str)
{
    axis2_char_t *temp_str = NULL;
    for(temp_str = str; *temp_str != '\0'; temp_str++)
    {
        *temp_str = (axis2_char_t)toupper((int)*temp_str);
        /* We are sure that the conversion is safe */
    }
    return str;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_strcasestr(
    const axis2_char_t *haystack,
    const axis2_char_t *needle)
{
    axis2_char_t start, current;
    size_t len;

    if(!haystack || !needle)
    {
        return NULL;
    }

    if((start = *needle++))
    {
        len = strlen(needle);
        do
        {
            do
            {
                if(!(current = *haystack++))
                {
                    return NULL;
                }
            }
            while(toupper((int)current) != toupper((int)start));
        }
        while(axutil_strncasecmp(haystack, needle, (int)len));
        /* We are sure that the difference lies within the int range */
        haystack--;
    }
    return (axis2_char_t *)haystack;
}
