/*
 * 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_utils.h>
#include <stdlib.h>
#include <axutil_string.h>
#include <string.h>
#include <platforms/axutil_platform_auto_sense.h>

AXIS2_EXPORT axis2_char_t *axis2_request_url_prefix = "services";

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_parse_rest_url_for_params(
    const axutil_env_t *env,
    const axis2_char_t *tmpl,
    const axis2_char_t *url,
    int *match_count,
    axis2_char_t ****matches)
{
    axis2_char_t ***ret = NULL;
    axis2_char_t *tmp1 = NULL;
    axis2_char_t **tmp2 = NULL;
    axis2_char_t ***tmp3 = NULL;
    axis2_char_t *tmp4 = NULL;
    axis2_char_t *resource = NULL;
    axis2_char_t *query = NULL;
    axis2_char_t *url_tmp = NULL;
    axis2_char_t *url_resource = NULL;
    axis2_char_t *url_query = NULL;
    axis2_bool_t finished = AXIS2_FALSE;
    axis2_status_t status = AXIS2_FAILURE;
    int ret_count = 0;
    int i = 0;
    int j = 0;
    axis2_bool_t in_tok = AXIS2_FALSE;

    tmp2 = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *)));
    memset(tmp2, 0, 2 * sizeof(axis2_char_t *));

    if (tmpl[0] == '/')
    {
        tmp1 = (axis2_char_t *) tmpl;
        tmp1++;
        resource = axutil_strdup(env, tmp1);
    }
    else
    {
        resource = axutil_strdup(env, tmpl);
    }
    i = (int)strlen(resource);
    /* We are sure that the difference lies within the int range */
    if (resource[i] == '/')
    {
        resource[i] = '\0';
    }
    tmp1 = strchr(resource, '?');
    if (tmp1)
    {
        axis2_char_t *tmp4 = NULL;
        
        tmp4 = tmp1;
        tmp1++;
        resource[tmp4 - resource] = '\0';
        if (*tmp1 && ((tmp1 - resource) < (int)strlen(resource) - 1))
            /* We are sure that the difference lies within the int range */
        {
            query = tmp1;
            /* 
             * Query String based matching is not implemented. This is
             * reserved for future implementations.
             */
        }
    }

    /* Validation of Template */
    i = (int)strlen(resource);
    /* We are sure that the difference lies within the int range */

    if (!strchr(resource, '{') && !strchr(resource, '}'))
    {
        i = 0;
    }
    for (j = 0; j < i; j++)
    {
        if (!in_tok)
        {
            if (resource[j] == '}')
            {
                AXIS2_FREE(env->allocator, resource);
                return AXIS2_FAILURE;
            }
            else if (resource[j] == '{')
            {
                if (j + 1 == i || resource[j + 1] == '}')
                {
                    AXIS2_FREE(env->allocator, resource);
                    return AXIS2_FAILURE;
                }
                else if (resource[j + 1] == '{')
                {
                    j++;
                }
                else
                {
                    in_tok = AXIS2_TRUE;
                }
            }
        }
        else
        {
            if (resource[j] == '{')
            {
                AXIS2_FREE(env->allocator, resource);
                return AXIS2_FAILURE;
            }
            else if (resource[j] == '}')
            {
                if (j + 1 < i && resource[j + 1] == '}')
                {
                    j++;
                }
                else
                {
                    in_tok = AXIS2_FALSE;
                }
            }
        }
    }
    if (in_tok)
    {
        AXIS2_FREE(env->allocator, resource);
        return AXIS2_FAILURE;
    }

    /* Validity of template guaranteed if not returned */

    if (url[0] == '/')
    {
        tmp1 = (axis2_char_t *) url;
        tmp1++;
        url_resource = axutil_strdup(env, tmp1);
    }
    else
    {
        url_resource = axutil_strdup(env, url);
    }
    i = (int)strlen(url_resource);

    /* We are sure that the difference lies within the int range */

    if (url_resource[i] == '/')
    {
        url_resource[i] = '\0';
    }
    i = 0;
    url_tmp = url_resource;
    tmp1 = strchr(url_resource, '?');
    if (tmp1)
    {
        axis2_char_t *tmp4 = NULL;
        
        tmp4 = tmp1;
        tmp1++;
        url_resource[tmp4 - url_resource] = '\0';
        if (*tmp1 && ((tmp1 - url_resource) < (int)strlen(url_resource) - 1))
            /* We are sure that the difference lies within the int range */
        {
            url_query = tmp1;
        }
    }
    tmp1 = resource;

    /* Simplest case match */

    if (!strchr(resource, '{'))
    {
        if (strcmp(resource, url_resource) == 0)
        {
            finished = AXIS2_TRUE;
        }
    }

    while (!finished)
    {
        tmp4 = strchr(tmp1, '{');
        if (tmp4 && tmp4[1])
        {
            if (tmp4[1] != '{')
            {
                axis2_char_t *tmp5 = NULL;
                axis2_char_t *tmp6 = NULL;
                axis2_char_t *tmp7 = NULL;
                axis2_char_t *tmp8 = NULL;
                axis2_char_t *tmp9 = NULL;

                /* Logic for finding out constant portion to match */
                i = (int)(tmp4 - tmp1);
                tmp2[0] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char));
                strncpy(tmp2[0], tmp1, i);
                tmp2[0][i] = '\0';
                if (url_tmp && *url_tmp)
                {
                    tmp6 = url_tmp;
                    tmp5 = strstr(tmp6, tmp2[0]);
                    if (tmp5)
                    {
                        tmp5 += strlen(tmp2[0]);
                        tmp7 = tmp4;
                        tmp8 = tmp4;
                        tmp7++;
                        if (*tmp7)
                        {
                            axis2_bool_t finished_tmp = AXIS2_FALSE;
                            while (!finished_tmp)
                            {
                                tmp6 = strchr(tmp8, '}');
                                if (tmp6 && *tmp6)
                                {
                                    if (tmp6[1] != '}')
                                    {
                                        tmp8 = tmp6 + 1;
                                        break;
                                    }
                                }
                                else
                                {
                                    finished_tmp = AXIS2_TRUE;
                                }
                            }
                            if (!finished_tmp && !strchr(tmp8, '{'))
                            {
                                tmp7 = tmp8 + strlen(tmp8);
                            }
                            else
                            {
                                while (!finished_tmp)
                                {
                                    tmp6 = strchr(tmp8, '{');
                                    if (tmp6 && tmp6[1])
                                    {
                                        if (tmp6[1] != '{')
                                        {
                                            tmp7 = tmp6;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        finished_tmp = AXIS2_TRUE;
                                    }
                                }
                            }
                            if (!finished_tmp)
                            {
                                i = (int)(tmp7 - tmp8);
                                tmp9 = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char));
                                strncpy(tmp9, tmp8, i);
                                tmp9[i] = '\0';
                            }
                        }
                        if (tmp9 && *tmp9)
                        {
                            tmp6 = strstr(tmp5, tmp9);
                            AXIS2_FREE (env->allocator, tmp9);
                            tmp9 = NULL;
                        }
                        else
                        {
                            tmp6 = strchr(tmp5, '/');
                        }
                        /* Logic for saving the match */
                        if (tmp6 && tmp6 != tmp5)
                        {
                            i = (int)(tmp6 - tmp5);
                            url_tmp = tmp6;
                            tmp2[1] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char));
                            strncpy(tmp2[1], tmp5, i);
                            tmp2[1][i] = '\0';
                        }
                        else
                        {
                            i = (int)strlen(tmp5);
                            /* We are sure that the difference lies within the int range */
                            tmp2[1] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char));
                            strncpy(tmp2[1], tmp5, i);
                            tmp2[1][i] = '\0';
                            url_tmp = NULL;
                        }
                    }
                }
                else
                {
                    break;
                }
                while (!finished)
                {
                    tmp1 = tmp4 + 1;
                    tmp4 = strchr(tmp1, '}');
                    if (tmp4 && *tmp4)
                    {
                        if (tmp4[1] != '}')
                        {
                            /* Logic for saving the key for the match */
                            i = (int)(tmp4 - tmp1);
                            if (tmp2[0])
                            {
                                AXIS2_FREE(env->allocator, tmp2[0]);
                            }
                            tmp2[0] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char));
                            strncpy(tmp2[0], tmp1, i);
                            tmp2[0][i] = '\0';
                            tmp3 = ret;
                            ret_count++;
                            ret = AXIS2_MALLOC(env->allocator, ret_count * 2 * (sizeof(axis2_char_t *)));
                            memset(ret, 0, ret_count * 2 * sizeof(axis2_char_t *));
                            for(i = 0; i < ret_count - 1; i++)
                            {
                                ret[i] = tmp3[i];
                            }
                            ret[i] = tmp2;
                            tmp2 = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *)));
                            memset(tmp2, 0, 2 * sizeof(axis2_char_t *));
                            tmp3 = NULL;
                            break;
                        }
                        else
                        {
                            tmp4++;
                        }
                    }
                    else
                    {
                        finished = AXIS2_TRUE;
                    }
                }
            }
            else
            {
                tmp4++;
            }
        }
        else
        {
            /* Result of mismatch at the simplest case */
            if (!strchr(resource, '{'))
            {
                finished = AXIS2_FALSE;
                break;
            }
            finished = AXIS2_TRUE;
        }
        tmp1 = tmp4 + 1;
    }
    if (resource)
    {
        AXIS2_FREE(env->allocator, resource);
    }
    if (url_resource)
    {
        AXIS2_FREE(env->allocator, url_resource);
    }
    if (tmp2)
    {
        if (tmp2[0])
        {
            AXIS2_FREE(env->allocator, tmp2[0]);
        }
        if (tmp2[1])
        {
            AXIS2_FREE(env->allocator, tmp2[1]);
        }
        AXIS2_FREE(env->allocator, tmp2);
    }
    if (finished)
    {
        status = AXIS2_SUCCESS;
    }
    *match_count = ret_count;
    *matches = ret;
    return status;
}

AXIS2_EXTERN axis2_char_t **AXIS2_CALL
axutil_parse_request_url_for_svc_and_op(
    const axutil_env_t *env,
    const axis2_char_t *request)
{
    axis2_char_t **ret = NULL;
    axis2_char_t *service_str = NULL;
    axis2_char_t *tmp = NULL;
    axis2_bool_t loop_state = AXIS2_TRUE;
    int i = 0;
    ret = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *)));
    memset(ret, 0, 2 * sizeof(axis2_char_t *));
    tmp = (axis2_char_t *) request;

    while (loop_state)
    {
        tmp = strstr(tmp, axis2_request_url_prefix);
        if (!tmp)
        {
            break;
        }
        else
        {
            service_str = tmp;
            tmp += axutil_strlen(axis2_request_url_prefix);
            break;  /* stop on first prefix as user may have prefix in service name */
        }
    }
    if (service_str)
    {
        service_str += axutil_strlen(axis2_request_url_prefix);
        if ('\0' != *service_str)
        {
            if (*service_str == '/')
                service_str++;  /*to remove the leading '/' */
            tmp = strchr(service_str, '/');
            if (tmp)
            {
                i = (int)(tmp - service_str);
                ret[0] = AXIS2_MALLOC(env->allocator, i * sizeof(char) + 1);
                strncpy(ret[0], service_str, i);
                ret[0][i] = '\0';

                /* Now search for the op */
                service_str = tmp;
                if ('\0' != *service_str)
                {
                    service_str++;
                    tmp = strchr(service_str, '?');
                    if (tmp)
                    {
                        i = (int)(tmp - service_str);
                        ret[1] =
                            AXIS2_MALLOC(env->allocator, i * sizeof(char) + 1);
                        strncpy(ret[1], service_str, i);
                        ret[1][i] = '\0';
                    }
                    else
                    {
                        ret[1] = axutil_strdup(env, service_str);
                    }
                }
            }
            else
            {
                ret[0] = axutil_strdup(env, service_str);
            }
        }
    }
    return ret;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_xml_quote_string(
    const axutil_env_t *env,
    const axis2_char_t *s,
    axis2_bool_t quotes)
{
    const char *scan;
    size_t len = 0;
    size_t extra = 0;
    char *qstr;
    char *qscan;
    char c;

    for (scan = s; (c = *scan) != '\0'; ++scan, ++len)
    {
        if (c == '<' || c == '>')
            extra += 3;         /* &lt; or &gt; */
        else if (c == '&')
            extra += 4;         /* &amp; */
        else if (quotes && c == '"')
            extra += 5;         /* &quot; */
    }

    /* nothing to do */
    if (extra == 0)
        return NULL;

    qstr = AXIS2_MALLOC(env->allocator, len + extra + 1);
    for (scan = s, qscan = qstr; (c = *scan) != '\0'; ++scan)
    {
        if (c == '<')
        {
            *qscan++ = '&';
            *qscan++ = 'l';
            *qscan++ = 't';
            *qscan++ = ';';
        }
        else if (c == '>')
        {
            *qscan++ = '&';
            *qscan++ = 'g';
            *qscan++ = 't';
            *qscan++ = ';';
        }
        else if (c == '&')
        {
            *qscan++ = '&';
            *qscan++ = 'a';
            *qscan++ = 'm';
            *qscan++ = 'p';
            *qscan++ = ';';
        }
        else if (quotes && c == '"')
        {
            *qscan++ = '&';
            *qscan++ = 'q';
            *qscan++ = 'u';
            *qscan++ = 'o';
            *qscan++ = 't';
            *qscan++ = ';';
        }
        else
        {
            *qscan++ = c;
        }
    }

    *qscan = '\0';
    return qstr;
}


AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_url_decode(
    const axutil_env_t *env,
    axis2_char_t *dest,
    axis2_char_t *src)
{
    AXIS2_PARAM_CHECK(env->error, dest, AXIS2_FAILURE);
    AXIS2_PARAM_CHECK(env->error, src, AXIS2_FAILURE);

    for (; *src != '\0'; ++dest, ++src)
    {
        if (src[0] == '%' && isxdigit(src[1]) && isxdigit(src[2]))
        {
            *dest = (axis2_char_t)(axutil_hexit(src[1]) * 16 + axutil_hexit(src[2]));
            /* We are sure that the conversion is safe */
            src += 2;
        }
        else
        {
            *dest = *src;
        }
    }
    *dest = '\0';

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_hexit(axis2_char_t c)
{
    if (c >= '0' && c <= '9')
    {
        return c - '0';
    }
    if (c >= 'a' && c <= 'f')
    {
        return c - 'a' + 10;
    }
    if (c >= 'A' && c <= 'F')
    {
        return c - 'A' + 10;
    }
    return 0;    
}
