/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *        * Redistributions of source code must retain the above copyright
 *            notice, this list of conditions and the following disclaimer.
 *        * Redistributions in binary form must reproduce the above copyright
 *            notice, this list of conditions and the following disclaimer in the
 *            documentation and/or other materials provided with the distribution.
 *        * Neither the name of The Linux Foundation nor
 *            the names of its contributors may be used to endorse or promote
 *            products derived from this software without specific prior written
 *            permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "ConfFileParser.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <utils/Log.h>

//declaration of functions only specific to this file
static char parse_line
(
  group_table *key_file,
  const char *line,
  char **cur_grp
);

static char parse_load_frm_fhandler
(
  group_table *key_file,
  FILE *fp
);

static char line_is_grp
(
  group_table *key_file,
  const char *str,
  char **cur_grp
);

static void free_grp_list
(
  group *a
);

static void free_key_list
(
  key_value_pair_list *a
);

static char line_is_key_value_pair
(
  group_table *key_file,
  const char *str,
  const char *cur_grp
);

static char line_is_comment
(
  const char *str
);

static char grp_exist
(
  const group_table *key_file,
  const char *new_grp
);

static char add_grp
(
  group_table *key_file,
  const char *new_grp
);

static group *alloc_group
(
  void
);

static key_value_pair_list *alloc_key_value_pair
(
  void
);

static char add_key_value_pair
(
  group_table *key_file,
  const char *cur_grp,
  const char *key,
  const char *val
);


//Definitions
void free_strs
(
  char **str_array
)
{
  char **str_array_cpy = str_array;
  if(str_array != NULL) {
     while(*str_array != NULL) {
           free(*str_array);
           str_array++;
     }
  }
  free(str_array_cpy);
}
//ToDo: Come up with code hashing
//function
unsigned int get_hash_code
(
  const char *str
)
{

  unsigned len = strlen(str);
  unsigned int i;
  unsigned int hash_code = 0;

  for(i = 0; len > 0; len--, i++) {
      hash_code += (int)((str[i] * pow(2, len))) % INT_MAX;
      hash_code %= INT_MAX;
  }
  return hash_code;
}

static key_value_pair_list *alloc_key_value_pair
(
  void
)
{
  key_value_pair_list *key_list = NULL;

  key_list = (key_value_pair_list *)malloc(
                                       sizeof(key_value_pair_list));
  if(key_list != NULL) {
     key_list->key = NULL;
     key_list->next = NULL;
     key_list->value = NULL;
  }
  return key_list;
}

static group * alloc_group
(
  void
)
{
  group *grp = NULL;
  unsigned int i;

  grp = (group *)malloc(sizeof(group));
  if(grp != NULL) {
     grp->grp_name = NULL;
     grp->grp_next = NULL;
     grp->num_of_keys = 0;
     grp->keys_hash_size = MAX_UNIQ_KEYS;
     grp->list = (key_value_pair_list **)malloc
                    (sizeof(key_value_pair_list *) * grp->keys_hash_size);
     if(grp->list == NULL) {
        ALOGE("Could not alloc group\n");
        free(grp);
        grp = NULL;
     }else {
        for(i = 0; i < grp->keys_hash_size; i++) {
            grp->list[i] = NULL;
        }
     }
  }
  return grp;
}

group_table *get_key_file
(
)
{
  group_table *t = NULL;
  unsigned int i;

  t = (group_table *)malloc(sizeof(group_table));
  if (t != NULL) {
      t->grps_hash_size = MAX_UNIQ_GRPS;
      t->num_of_grps = 0;
      t->grps_hash = (group **)malloc(sizeof(group *)
                                       * t->grps_hash_size);
      if (t->grps_hash == NULL) {
          free(t);
          return NULL;
      }
      for(i = 0; i < t->grps_hash_size; i++) {
          t->grps_hash[i] = NULL;
      }
  }
  return t;
}

void free_key_file(
  group_table *key_file
)
{
  unsigned int i;

  if(key_file != NULL) {
     if(key_file->grps_hash != NULL) {
        for(i = 0; i < key_file->grps_hash_size; i++) {
            free_grp_list(key_file->grps_hash[i]);
        }
     }
     free(key_file->grps_hash);
     free(key_file);
  }
}

static void free_grp_list
(
  group *a
)
{
  group *next;
  unsigned int i;

  while(a != NULL) {
       next = a->grp_next;
       if(a->list != NULL) {
          for(i = 0; i < a->keys_hash_size; i++) {
              free_key_list(a->list[i]);
          }
       }
       free(a->grp_name);
       free(a->list);
       free(a);
       a = next;
  }
}

static void free_key_list
(
  key_value_pair_list *a
)
{
  key_value_pair_list *next;

  while(a != NULL) {
       next = a->next;
       free(a->key);
       free(a->value);
       free(a);
       a = next;
  }
}
//return all the groups
//present in the file
char **get_grps
(
  const group_table *key_file
)
{
  char **grps = NULL;
  unsigned int i = 0;
  unsigned int j = 0;
  unsigned int grp_len;
  group *grp_list;

  if((key_file == NULL)
     || (key_file->grps_hash == NULL)
     || (key_file->grps_hash_size == 0)
     || (key_file->num_of_grps == 0)) {
     return grps;
  }
  grps = (char **)calloc((key_file->num_of_grps + 1),
                           sizeof(char *));
  if(grps == NULL) {
     return grps;
  }
  for(i = 0; i < key_file->grps_hash_size; i++) {
      grp_list = key_file->grps_hash[i];
      while(grp_list != NULL) {
            grp_len = strlen(grp_list->grp_name);
            grps[j] = (char *)malloc(sizeof(char) *
                                     (grp_len + 1));
            if(grps[j] == NULL) {
               free_strs(grps);
               grps = NULL;
               return grps;
            }
            memcpy(grps[j], grp_list->grp_name,
                   (grp_len + 1));
            grp_list = grp_list->grp_next;
            j++;
      }
  }
  grps[j] = NULL;
  return grps;
}

//returns the list of keys
//associated with group name
char **get_keys
(
  const group_table *key_file,
  const char *grp_name
)
{
  unsigned int grp_hash_code;
  unsigned int grp_index;
  unsigned int i;
  unsigned int j = 0;
  unsigned int key_len;
  group *grp;
  key_value_pair_list *key_val_list;
  char **keys = NULL;

  if((key_file == NULL) || (grp_name == NULL)
     || (key_file->num_of_grps == 0) ||
     (key_file->grps_hash_size == 0) ||
     (key_file->grps_hash == NULL) ||
     (!strcmp(grp_name, ""))) {
      return keys;
  }
  grp_hash_code = get_hash_code(grp_name);
  grp_index = (grp_hash_code % key_file->grps_hash_size);
  grp = key_file->grps_hash[grp_index];
  while(grp != NULL) {
        if(!strcmp(grp_name, grp->grp_name)) {
            if((grp->num_of_keys == 0)
               || (grp->keys_hash_size == 0)
               || (grp->list == 0)) {
               return keys;
            }
            keys = (char **)calloc((grp->num_of_keys + 1),
                                   sizeof(char *));
            if(keys == NULL) {
                return keys;
            }
            for(i = 0; i < grp->keys_hash_size; i++) {
                key_val_list = grp->list[i];
                while(key_val_list != NULL) {
                     key_len = strlen(key_val_list->key);
                     keys[j] = (char *)malloc(sizeof(char) *
                                              (key_len + 1));
                     if(keys[j] == NULL) {
                         free_strs(keys);
                         keys = NULL;
                         return keys;
                     }
                     memcpy(keys[j], key_val_list->key,
                            (key_len + 1));
                     j++;
                     key_val_list = key_val_list->next;
                }
            }
            keys[j] = NULL;
            return keys;
        }
        grp = grp->grp_next;
  }
  return keys;
}

char *get_value
(
   const group_table *key_file,
   const char *grp_name,
   const char *key
)
{
   unsigned int grp_hash_code;
   unsigned int key_hash_code;
   unsigned int grp_index;
   unsigned int key_index;
   unsigned val_len;
   char *val = NULL;
   group *grp;
   key_value_pair_list *list;

   if((key_file == NULL) || (grp_name == NULL)
      || (key == NULL) || (key_file->grps_hash == NULL)
      || (key_file->grps_hash_size == 0) || !strcmp(grp_name, "")
      ||(!strcmp(key, ""))) {
       return NULL;
   }
   grp_hash_code = get_hash_code(grp_name);
   key_hash_code = get_hash_code(key);
   grp_index = (grp_hash_code % key_file->grps_hash_size);
   grp = key_file->grps_hash[grp_index];
   while(grp != NULL) {
         if(!strcmp(grp_name, grp->grp_name) && grp->keys_hash_size
            && grp->list) {
            key_index = (key_hash_code % grp->keys_hash_size);
            list = grp->list[key_index];
            while((list != NULL) && (strcmp(list->key, key))) {
                   list = list->next;
            }
            if(list != NULL) {
                val_len = strlen(list->value);
                val = (char *)malloc(sizeof(char) * (val_len + 1));
                if(val != NULL) {
                   memcpy(val, list->value, val_len);
                   val[val_len] = '\0';
                }
            }
            return val;
         }
         grp = grp->grp_next;
   }
   return val;
}
//open the file,
//read, parse and load
//returns PARSE_SUCCESS if successfully
//loaded else PARSE_FAILED
char parse_load_file
(
  group_table *key_file,
  const char *file
)
{
  FILE *fp;
  char ret = FALSE;

  if((file == NULL) || !strcmp(file, "")) {
     ALOGE("File name is null or empty \n");
     return ret;
  }

  fp = fopen(file, "r");
  if(fp == NULL) {
     ALOGE("could not open file for read\n");
     return ret;
  }

  ret = parse_load_frm_fhandler(key_file, fp);
  fclose(fp);

  return ret;
}

//Read block of data from file handler
//extract each line, check kind of line(comment,
//group, key value pair)
static char parse_load_frm_fhandler
(
  group_table *key_file,
  FILE *fp
)
{
  char buf[MAX_LINE_LEN];
  char ret = TRUE;
  char *line = NULL;
  void *new_line;
  char *cur_grp = NULL;
  unsigned line_len = 0;
  unsigned line_allocated = 0;
  unsigned int bytes_read = 0;
  unsigned int i;
  bool has_carriage_rtn = false;

  while((bytes_read = fread(buf, 1, MAX_LINE_LEN, fp))) {
        for(i = 0; i < bytes_read; i++) {
            if(line_len == line_allocated) {
                line_allocated += 25;
                new_line = realloc(line, line_allocated);
                if(new_line == NULL) {
                   ret = FALSE;
                   ALOGE("memory allocation failed for line\n");
                   break;
                }
                line = (char *)new_line;
            }
            if(buf[i] == '\n') {
                has_carriage_rtn = false;
                line[line_len] = '\0';
                ret = parse_line(key_file, line, &cur_grp);
                line_len = 0;
                if(ret == FALSE) {
                   ALOGE("could not parse the line, line not proper\n");
                   break;
                }
            }else if(buf[i] == '\r') {
                ALOGE("File has carriage return\n");
                has_carriage_rtn = true;
            }else if(has_carriage_rtn) {
                ALOGE("File format is not proper, no line character\
                        after carraige return\n");
                ret = FALSE;
                break;
            }else {
                line[line_len] = buf[i];
                line_len++;
            }
        }
        if (!ret) {
            break;
        }
  }
  free(line);
  free(cur_grp);

  return ret;
}

//checks whether a line is
//comment or grp or key pair value
//and accordingly adds to list
static char parse_line
(
  group_table *key_file,
  const char *line,
  char **cur_grp
)
{
  const char *line_begin;

  if((line == NULL) || (key_file == NULL)) {
      ALOGE("key file or line is null\n");
      return FALSE;
  }

  for(line_begin = line; isspace(*line_begin);
          line_begin++);

  if(line_is_comment(line_begin)) {
      ALOGE("line is comment\n");
      return TRUE;
  }else if(line_is_grp(key_file, line_begin, cur_grp)) {
      ALOGE("line is grp\n");
      return TRUE;
  }else if(line_is_key_value_pair(key_file, line_begin, *cur_grp)) {
      ALOGE("line is key value pair\n");
      return TRUE;
  }else {
     ALOGE("line is neither comment, grp nor key value pair\n");
     return FALSE;
  }
}

static char line_is_comment
(
  const char *str
)
{
  if(str == NULL) {
      return FALSE;
  }else if(((*str) == '#') || ((*str) == '\0')
       || ((*str) == '\n')) {
      return TRUE;
  }else {
      ALOGE("line is not comment\n");
      return FALSE;
  }
}

//return true if a group
//name already exist
//else false
static char grp_exist
(
  const group_table *key_file,
  const char *new_grp
)
{
  unsigned hash_code;
  unsigned int index;
  group *grp;

  if((key_file == NULL) || (new_grp == NULL)
     || (!key_file->grps_hash_size)) {
     return FALSE;
  }else {
    hash_code = get_hash_code(new_grp);
    index = hash_code % key_file->grps_hash_size;
    grp = key_file->grps_hash[index];
    while(grp != NULL) {
          if (!strcmp(grp->grp_name, new_grp))
              return TRUE;
          grp = grp->grp_next;
    }
    return FALSE;
  }
}

//Add a group to group
//table if it does not exist
static char add_grp
(
  group_table *key_file,
  const char *new_grp
)
{
  unsigned int hash_code;
  unsigned int index;
  unsigned int grp_name_len;
  group *grp;

  if(!grp_exist(key_file, new_grp)) {
      if((key_file == NULL) || (new_grp == NULL)
         || !key_file->grps_hash_size) {
         return FALSE;
      }
      hash_code = get_hash_code(new_grp);
      ALOGE("group hash code is: %u\n", hash_code);
      index = hash_code % key_file->grps_hash_size;
      ALOGE("group index is: %u\n", index);
      grp = alloc_group();
      if(grp == NULL) {
         return FALSE;
      }
      grp_name_len = strlen(new_grp);
      grp->grp_name = (char *)malloc(
                                  sizeof(char) * (grp_name_len + 1));
      if(grp->grp_name == NULL) {
         ALOGE("could not alloc memory for group name\n");
         ALOGE("Add group failed\n");
         free_grp_list(grp);
         return FALSE;
      }else {
         memcpy(grp->grp_name, new_grp, (grp_name_len + 1));
      }
      grp->grp_next = key_file->grps_hash[index];
      key_file->grps_hash[index] = grp;
      key_file->num_of_grps++;
      return TRUE;
  }else {
     return FALSE;
  }
}

//checks validity of a group
//a valid group is
//inside [] group name must be
//alphanumeric
//Example: [grpName]
static char line_is_grp
(
  group_table *key_file,
  const char *str,
  char **cur_grp
)
{
  const char *g_start;
  const char *g_end;
  char *new_grp;
  unsigned int grp_len;

  if ((str == NULL) || (key_file == NULL)) {
      ALOGE("str is null or key file is null\n");
      return FALSE;
  }
  //checks start mark char ']'
  if(((*str) != '[')) {
      ALOGE("start mark is not '['\n");
      return FALSE;
  }else {
      str++;
      g_start = str;
  }
  //checks the end char '['
  while((*str != '\0') && ((*str) != ']')) {
        str++;
  }
  //if end mark group not found
  if ((*str) != ']') {
       ALOGE("grp end mark is not '['\n");
       return FALSE;
  }else {
       g_end = (str - 1);
  }

  str++;
  //if end mark found checks the rest chars as well
  //rest chars should be space
  while(((*str) == ' ') || ((*str) == '\t')) {
        str++;
  }
  if(*str) {
     ALOGE("after ']' there are some character\n");
     return FALSE;
  }

  str = g_start;
  while((*g_start != '\0') && (g_start != g_end)
         && isalnum(*g_start)) {
        g_start++;
  }
  if((g_start == g_end) && isalnum(*g_start)) {
      //look up if already exist
      //return false else insert the grp in grp table
      grp_len = (g_end - str + 1);
      new_grp = (char *)malloc(sizeof(char) * (grp_len + 1));
      if (new_grp == NULL) {
          ALOGE("could not alloc memory for new group\n");
          return FALSE;
      }
      memcpy(new_grp, str, grp_len);
      new_grp[grp_len] = '\0';

      if(add_grp(key_file, new_grp)) {
          free(*cur_grp);
         *cur_grp = new_grp;
         return TRUE;
      }else {
         ALOGE("could not add group to group table\n");
         return FALSE;
      }
  }else {
      return FALSE;
  }
}

//checks validity of key
//a valid key must start in
//a seperate line and key must
//be alphanumeric and before '='
//there must not be any space
//Example: key=value
static char line_is_key_value_pair
(
  group_table *key_file,
  const char *str,
  const char *cur_grp
)
{
  const char *equal_start;
  char *key = NULL;
  char *val = NULL;
  unsigned key_len;
  unsigned val_len;

  if((str == NULL) || (cur_grp == NULL) ||
     !strcmp(cur_grp, "") || (key_file == NULL)) {
     ALOGE("line is null or cur group or key file is null or empty\n");
     return FALSE;
  }
  equal_start = strchr(str, '=');
  key_len = (equal_start - str);
  if((equal_start == NULL) || (equal_start == str)) {
     ALOGE("line does not have '=' character or no key\n");
     return FALSE;
  }
  while((str != equal_start) && isalnum(*str))
        str++;
  if(str == equal_start) {
      key = (char *)malloc(sizeof(char) * (key_len + 1));
      if(key == NULL) {
         ALOGE("could not alloc memory for new key\n");
         return FALSE;
      }
      equal_start++;
      val_len = strlen(equal_start);
      val = (char *)malloc(sizeof(char) * (val_len + 1));
      if(val == NULL) {
         ALOGE("could not alloc memory for value\n");
         if(key){
             free(key);
             key = NULL;
         }
         return FALSE;
      }
      memcpy(key, (str - key_len), key_len);
      memcpy(val, equal_start, val_len);
      key[key_len] = '\0';
      val[val_len] = '\0';
      ALOGE("Grp: %s, key: %s, value: %s\n", cur_grp, key, val);
      return add_key_value_pair(key_file,
                                 cur_grp, key, val);
  }else {
     ALOGE("key name doesnot have alpha numeric char\n");
     return FALSE;
  }
}

static char add_key_value_pair
(
  group_table *key_file,
  const char *cur_grp,
  const char *key,
  const char *val
)
{
  unsigned int grp_hash_code;
  unsigned int key_hash_code;
  unsigned int grp_index;
  unsigned int key_index;
  unsigned key_len = 0;
  unsigned val_len = 0;
  group *grp = NULL;
  key_value_pair_list *list = NULL;

  if((key_file != NULL) && (cur_grp != NULL)
      && (key != NULL) && ((key_file->grps_hash != NULL))
      && (strcmp(key, ""))) {
     grp_hash_code = get_hash_code(cur_grp);
     ALOGE("grp hash code is %u\n", grp_hash_code);
     grp_index = (grp_hash_code % key_file->grps_hash_size);
     ALOGE("grp index is %u\n", grp_index);
     grp = key_file->grps_hash[grp_index];
     key_hash_code = get_hash_code(key);
     while((grp != NULL)) {
           if(!strcmp(cur_grp, grp->grp_name)) {
              key_index = (key_hash_code % grp->keys_hash_size);
              if(grp->list) {
                 list = grp->list[key_index];
              }else {
                 ALOGE("group list is null\n");
                 goto err;
              }
              while((list != NULL) && strcmp(key, list->key)) {
                    list = list->next;
              }
              if(list != NULL) {
                  ALOGE("group already contains the key\n");
                  goto err;
              }else{
                  list = alloc_key_value_pair();
                  if(list == NULL) {
                     ALOGE("add key value failed as could not alloc memory for key\
                            val pair\n");
                     goto err;
                  }
                  if(key) {
                      key_len = strlen(key);
                  }
                  list->key = (char *)malloc(sizeof(char) *
                                              (key_len + 1));
                  if(list->key == NULL) {
                     ALOGE("could not alloc memory for key\n");
                     free(list);
                     goto err;
                  }
                  if(val) {
                      val_len = strlen(val);
                  }
                  list->value = (char *)malloc(sizeof(char) *
                                                (val_len + 1));
                  if(!list->value) {
                      free(list->key);
                      free(list);
                      goto err;
                  }
                  memcpy(list->key, key, key_len);
                  memcpy(list->value, val, val_len);
                  if (key) free((char*)key);
                  if (val) free((char*)val);
                  list->key[key_len] = '\0';
                  list->value[val_len] = '\0';
                  list->next = grp->list[key_index];
                  grp->list[key_index] = list;
                  grp->num_of_keys++;
                  return TRUE;
              }
           }
           grp = grp->grp_next;
     }
     ALOGE("group does not exist\n");
     goto err;
  }
err:
     if (key) free((char*)key);
     if (val) free((char*)val);
     return FALSE;
}
