/*
 * 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 <guththila_token.h>
    
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
    
#define TOK_LIST_FREE(tok_list) \
    (if (tok_list) { AXIS2_FREE(tok_list)} )
    
#define TOK_LIST_SIZE(tok_list) (tok_list->size)


int GUTHTHILA_CALL
guththila_tok_list_grow(
    guththila_tok_list_t * tok_list,
    const axutil_env_t * env) 
{
    int i = 0;
    int cur = 0;
    int cur_cap = 0;
    guththila_token_t ** list = NULL;
    if (tok_list->cur_list < tok_list->no_list - 1)
    {
        cur = ++tok_list->cur_list;
        cur_cap = tok_list->capacity[cur - 1] * 2;
        tok_list->list[cur] =
            (guththila_token_t *) AXIS2_MALLOC(env->allocator,
                                               sizeof(guththila_token_t) *
                                               cur_cap);
        for (i = 0; i < cur_cap; i++)
        {
            guththila_stack_push(&tok_list->fr_stack, &tok_list->list[cur][i],
                                  env);
        }
        tok_list->capacity[cur] = cur_cap;
        return GUTHTHILA_SUCCESS;
    }
    else
    {
        list =
            (guththila_token_t **) AXIS2_MALLOC(env->allocator,
                                                sizeof(guththila_token_t *) *
                                                tok_list->no_list * 2);
        if (list)
        {
            for (i = 0; i <= tok_list->cur_list; i++)
            {
                list[i] = tok_list->list[i];
            }
            tok_list->no_list = tok_list->no_list * 2;
            AXIS2_FREE(env->allocator, tok_list->list);
            tok_list->list = list;
            guththila_tok_list_grow(tok_list, env);
        }
    }
    return GUTHTHILA_FAILURE;
}
int GUTHTHILA_CALL
guththila_tok_list_init(
    guththila_tok_list_t * tok_list,
    const axutil_env_t * env) 
{
    int i = 0;
    tok_list->list =
        (guththila_token_t **) AXIS2_MALLOC(env->allocator,
                                            sizeof(guththila_token_t *) *
                                            GUTHTHILA_TOK_DEF_LIST_SIZE);
    if (tok_list->list && guththila_stack_init(&tok_list->fr_stack, env))
    {
        tok_list->capacity =
            (int *) AXIS2_MALLOC(env->allocator,
                                 sizeof(int) * GUTHTHILA_TOK_DEF_LIST_SIZE);
        if (tok_list->capacity)
        {
            tok_list->no_list = GUTHTHILA_TOK_DEF_LIST_SIZE;
            tok_list->list[0] =
                (guththila_token_t *) AXIS2_MALLOC(env->allocator,
                                                   sizeof(guththila_token_t) *
                                                   GUTHTHILA_TOK_DEF_SIZE);
            for (i = 0; i < GUTHTHILA_TOK_DEF_SIZE; i++)
            {
                guththila_stack_push(&tok_list->fr_stack,
                                      &tok_list->list[0][i], env);
            }
            tok_list->capacity[0] = GUTHTHILA_TOK_DEF_SIZE;
            tok_list->cur_list = 0;
            tok_list->no_list = GUTHTHILA_TOK_DEF_LIST_SIZE;
            return GUTHTHILA_SUCCESS;
        }
    }
    return GUTHTHILA_FAILURE;
}
void GUTHTHILA_CALL
guththila_tok_list_free(
    guththila_tok_list_t * tok_list,
    const axutil_env_t * env) 
{
    int i = 0;
    guththila_stack_un_init(&tok_list->fr_stack, env);
    for (; i <= tok_list->cur_list; i++)
    {
        AXIS2_FREE(env->allocator, tok_list->list[i]);
    }
    AXIS2_FREE(env->allocator, tok_list->list);
    AXIS2_FREE(env->allocator,tok_list->capacity);
    AXIS2_FREE(env->allocator, tok_list);
}
void GUTHTHILA_CALL
guththila_tok_list_free_data(
    guththila_tok_list_t * tok_list,
    const axutil_env_t * env) 
{
    int i = 0;
    guththila_stack_un_init(&tok_list->fr_stack, env);
    for (; i <= tok_list->cur_list; i++)
    {
        AXIS2_FREE(env->allocator, tok_list->list[i]);
    }
    AXIS2_FREE(env->allocator,tok_list->capacity);
    AXIS2_FREE(env->allocator, tok_list->list);
}
guththila_token_t *GUTHTHILA_CALL
guththila_tok_list_get_token(guththila_tok_list_t * tok_list,
                                                const axutil_env_t * env) 
{
    if (tok_list->fr_stack.top > 0 || guththila_tok_list_grow(tok_list, env))
    {
        return guththila_stack_pop(&tok_list->fr_stack, env);
    }
    return NULL;
}
int GUTHTHILA_CALL
guththila_tok_list_release_token(
    guththila_tok_list_t * tok_list,
    guththila_token_t * token,
    const axutil_env_t * env) 
{
    return guththila_stack_push(&tok_list->fr_stack, token, env);
}
int GUTHTHILA_CALL
guththila_tok_str_cmp(
    guththila_token_t * tok,
    guththila_char_t *str,
    size_t str_len,
    const axutil_env_t * env) 
{
    unsigned int i = 0;
    if (tok->size != str_len)
        return -1;
    for (; i < tok->size; i++)
    {
        if (tok->start[i] != str[i])
        {
            return -1;
        }
    }
    return 0;
}
int GUTHTHILA_CALL
guththila_tok_tok_cmp(
    guththila_token_t * tok1,
    guththila_token_t * tok2,
    const axutil_env_t * env) 
{
    unsigned int i = 0;

    if (tok1 && tok2)
    {
        if (tok1->size != tok2->size)
            return -1;
        for (; i < tok1->size; i++)
        {
            if (tok1->start[i] != tok2->start[i])
            {
               return -1;
            }
        }
		return 0;
    }
    return -1;
}
void GUTHTHILA_CALL
guththila_set_token(guththila_token_t* tok,
                       guththila_char_t* start,
                       short type,
                       int size,
                       int _start,
                       int last,
                       int ref,
                       const axutil_env_t* env)
{
    if(start)
    {
        tok->start = start;
        tok->type = type;
        tok->_start = _start;
        tok->size = size;
        tok->last = last;
        tok->ref = ref;
    }
}
