#include "config_file_process.h"

#include <fstream>

std::string trim(std::string const& source, char const* delims = " \t\r\n") {
  std::string result(source);
  std::string::size_type index = result.find_last_not_of(delims);
  if(index != std::string::npos)
    result.erase(++index);

  index = result.find_first_not_of(delims);
  if(index != std::string::npos)
    result.erase(0, index);
  else
    result.erase();
  return result;
}

ConfigFile::ConfigFile(std::string const& configFilePath) {
  reloadConfigFile(configFilePath);
}

bool ConfigFile::reloadConfigFile(std::string const& configFilePath) {
  std::ifstream file(configFilePath.c_str());

  if(!file){
    X_INFO(stdout,"config param file not exist,path [%s]",configFilePath.c_str());
    exit(0);
  }

  std::string line;
  std::string name;
  std::string value;
  std::string inSection;
  unsigned long posEqual;
  content_.clear();
  while (std::getline(file,line)) {

    if (! line.length()) continue;

    if (line[0] == '#') continue;
    if (line[0] == ';') continue;

    if (line[0] == '[') {
      inSection=trim(line.substr(1,line.find(']')-1));
      continue;
    }

    posEqual=line.find('=');
    name  = trim(line.substr(0,posEqual));
    value = trim(line.substr(posEqual+1));

    std::string key = inSection;
    key.append("/");
    key.append(name);
    content_[key]=Chameleon(value);
  }
  return true;
}

bool ConfigFile::CheckConfExists(const std::string &entry) const {
  auto ci = content_.find('/' + entry);
#if (defined(BRANCH_ZXZQ) || defined(BRANCH_DBZQ) || defined(BRANCH_GTZQ))
  if(entry == "CreateRtnOrderByRtnTrade"){
    return true;
  }
#endif
  if(ci == content_.end()){
    X_INFO(stdout,"key [%s] not exist, use default value",entry.c_str());
    return false;
  } else{
    return true;
  }
}

Chameleon const& ConfigFile::Value(std::string const &entry) const {
  auto ci = content_.find('/' + entry);
#if (defined(BRANCH_ZXZQ) || defined(BRANCH_DBZQ) || defined(BRANCH_GTZQ))
  if(entry == "CreateRtnOrderByRtnTrade"){
    return emptyChameleon_;
  }
#endif
  if(ci == content_.end()){
    return emptyChameleon_;
  } else{
    return ci->second;
  }
}

Chameleon const& ConfigFile::Value(std::string const& section, std::string const& entry) const {

  auto ci = content_.find(section + '/' + entry);

  if (ci == content_.end()){
    return emptyChameleon_;
  }

  return ci->second;
}

Chameleon const& ConfigFile::Value(std::string const& section, std::string const& entry, double value) {
  try {
    return Value(section, entry);
  } catch(const char *) {
    return content_.insert(std::make_pair(section+'/'+entry, Chameleon(value))).first->second;
  }
}

Chameleon const& ConfigFile::Value(std::string const& section, std::string const& entry, std::string const& value) {
  try {
    return Value(section, entry);
  } catch(const char *) {
    return content_.insert(std::make_pair(section+'/'+entry, Chameleon(value))).first->second;
  }
}
