/**
 * 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 "configuration.h"


char * hadoop_conf_dir;

struct configuration config={.size=0, .confdetails=NULL};

//clean up method for freeing configuration
void free_configurations() {
  int i = 0;
  for (i = 0; i < config.size; i++) {
    if (config.confdetails[i]->key != NULL) {
      free((void *)config.confdetails[i]->key);
    }
    if (config.confdetails[i]->value != NULL) {
      free((void *)config.confdetails[i]->value);
    }
    free(config.confdetails[i]);
  }
  if (config.size > 0) {
    free(config.confdetails);
  }
  config.size = 0;
}

//function used to load the configurations present in the secure config
void get_configs() {
  FILE *conf_file;
  char *line;
  char *equaltok;
  char *temp_equaltok;
  size_t linesize = 1000;
  int size_read = 0;
  int str_len = 0;
  char *file_name = NULL;

#ifndef HADOOP_CONF_DIR
  str_len = strlen(CONF_FILE_PATTERN) + strlen(hadoop_conf_dir);
  file_name = (char *) malloc(sizeof(char) * (str_len + 1));
#else
  str_len = strlen(CONF_FILE_PATTERN) + strlen(HADOOP_CONF_DIR);
  file_name = (char *) malloc(sizeof(char) * (str_len + 1));
#endif

  if (file_name == NULL) {
    fprintf(LOGFILE, "Malloc failed :Out of memory \n");
    return;
  }
  memset(file_name,'\0',str_len +1);
#ifndef HADOOP_CONF_DIR
  snprintf(file_name,str_len, CONF_FILE_PATTERN, hadoop_conf_dir);
#else
  snprintf(file_name, str_len, CONF_FILE_PATTERN, HADOOP_CONF_DIR);
#endif

#ifdef DEBUG
  fprintf(LOGFILE, "get_configs :Conf file name is : %s \n", file_name);
#endif

  //allocate space for ten configuration items.
  config.confdetails = (struct confentry **) malloc(sizeof(struct confentry *)
      * MAX_SIZE);
  config.size = 0;
  conf_file = fopen(file_name, "r");
  if (conf_file == NULL) {
    fprintf(LOGFILE, "Invalid conf file provided : %s \n", file_name);
    free(file_name);
    return;
  }
  while(!feof(conf_file)) {
    line = (char *) malloc(linesize);
    if(line == NULL) {
      fprintf(LOGFILE, "malloc failed while reading configuration file.\n");
      goto cleanup;
    }
    size_read = getline(&line,&linesize,conf_file);
    //feof returns true only after we read past EOF.
    //so a file with no new line, at last can reach this place
    //if size_read returns negative check for eof condition
    if (size_read == -1) {
      if(!feof(conf_file)){
        fprintf(LOGFILE, "getline returned error.\n");
        goto cleanup;
      }else {
        break;
      }
    }
    //trim the ending new line
    line[strlen(line)-1] = '\0';
    //comment line
    if(line[0] == '#') {
      free(line);
      continue;
    }
    //tokenize first to get key and list of values.
    //if no equals is found ignore this line, can be an empty line also
    equaltok = strtok_r(line, "=", &temp_equaltok);
    if(equaltok == NULL) {
      free(line);
      continue;
    }
    config.confdetails[config.size] = (struct confentry *) malloc(
            sizeof(struct confentry));
    if(config.confdetails[config.size] == NULL) {
      fprintf(LOGFILE,
          "Failed allocating memory for single configuration item\n");
      goto cleanup;
    }

#ifdef DEBUG
    fprintf(LOGFILE, "get_configs : Adding conf key : %s \n", equaltok);
#endif

    memset(config.confdetails[config.size], 0, sizeof(struct confentry));
    config.confdetails[config.size]->key = (char *) malloc(
            sizeof(char) * (strlen(equaltok)+1));
    strcpy((char *)config.confdetails[config.size]->key, equaltok);
    equaltok = strtok_r(NULL, "=", &temp_equaltok);
    if (equaltok == NULL) {
      fprintf(LOGFILE, "configuration tokenization failed \n");
      goto cleanup;
    }
    //means value is commented so don't store the key
    if(equaltok[0] == '#') {
      free(line);
      free((void *)config.confdetails[config.size]->key);
      free(config.confdetails[config.size]);
      continue;
    }

#ifdef DEBUG
    fprintf(LOGFILE, "get_configs : Adding conf value : %s \n", equaltok);
#endif

    config.confdetails[config.size]->value = (char *) malloc(
            sizeof(char) * (strlen(equaltok)+1));
    strcpy((char *)config.confdetails[config.size]->value, equaltok);
    if((config.size + 1) % MAX_SIZE  == 0) {
      config.confdetails = (struct confentry **) realloc(config.confdetails,
          sizeof(struct confentry **) * (MAX_SIZE + config.size));
      if (config.confdetails == NULL) {
        fprintf(LOGFILE,
            "Failed re-allocating memory for configuration items\n");
        goto cleanup;
      }
    }
    if(config.confdetails[config.size] )
    config.size++;
    free(line);
  }

  //close the file
  fclose(conf_file);
  //clean up allocated file name
  free(file_name);
  return;
  //free spaces alloced.
  cleanup:
  if (line != NULL) {
    free(line);
  }
  fclose(conf_file);
  free(file_name);
  free_configurations();
  return;
}

/*
 * function used to get a configuration value.
 * The function for the first time populates the configuration details into
 * array, next time onwards used the populated array.
 *
 */
const char * get_value(const char* key) {
  int count;
  if (config.size == 0) {
    get_configs();
  }
  if (config.size == 0) {
    fprintf(LOGFILE, "Invalid configuration provided\n");
    return NULL;
  }
  for (count = 0; count < config.size; count++) {
    if (strcmp(config.confdetails[count]->key, key) == 0) {
      return strdup(config.confdetails[count]->value);
    }
  }
  return NULL;
}

/**
 * Function to return an array of values for a key.
 * Value delimiter is assumed to be a comma.
 */
const char ** get_values(const char * key) {
  const char ** toPass = NULL;
  const char *value = get_value(key);
  char *tempTok = NULL;
  char *tempstr = NULL;
  int size = 0;
  int len;
  //first allocate any array of 10
  if(value != NULL) {
    toPass = (const char **) malloc(sizeof(char *) * MAX_SIZE);
    tempTok = strtok_r((char *)value, ",", &tempstr);
    if (tempTok != NULL) {
      while (1) {
        toPass[size++] = tempTok;
        tempTok = strtok_r(NULL, ",", &tempstr);
        if(tempTok == NULL){
          break;
        }
        if((size % MAX_SIZE) == 0) {
          toPass = (const char **) realloc(toPass,(sizeof(char *) *
              (MAX_SIZE * ((size/MAX_SIZE) +1))));
        }
      }
    } else {
      toPass[size] = (char *)value;
    }
  }
  if(size > 0) {
    toPass[size] = NULL;
  }
  return toPass;
}

