/*
 *  Copyright 2008 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/optionsfile.h"

#include <ctype.h>

#include "rtc_base/logging.h"
#include "rtc_base/stream.h"
#include "rtc_base/stringencode.h"

namespace rtc {

OptionsFile::OptionsFile(const std::string &path) : path_(path) {
}

OptionsFile::~OptionsFile() = default;

bool OptionsFile::Load() {
  options_.clear();
  // Open file.
  FileStream stream;
  int err;
  if (!stream.Open(path_, "r", &err)) {
    RTC_LOG_F(LS_WARNING) << "Could not open file, err=" << err;
    // We do not consider this an error because we expect there to be no file
    // until the user saves a setting.
    return true;
  }
  // Read in all its data.
  std::string line;
  StreamResult res;
  for (;;) {
    res = stream.ReadLine(&line);
    if (res != SR_SUCCESS) {
      break;
    }
    size_t equals_pos = line.find('=');
    if (equals_pos == std::string::npos) {
      // We do not consider this an error. Instead we ignore the line and
      // keep going.
      RTC_LOG_F(LS_WARNING) << "Ignoring malformed line in " << path_;
      continue;
    }
    std::string key(line, 0, equals_pos);
    std::string value(line, equals_pos + 1, line.length() - (equals_pos + 1));
    options_[key] = value;
  }
  if (res != SR_EOS) {
    RTC_LOG_F(LS_ERROR) << "Error when reading from file";
    return false;
  } else {
    return true;
  }
}

bool OptionsFile::Save() {
  // Open file.
  FileStream stream;
  int err;
  if (!stream.Open(path_, "w", &err)) {
    RTC_LOG_F(LS_ERROR) << "Could not open file, err=" << err;
    return false;
  }
  // Write out all the data.
  StreamResult res = SR_SUCCESS;
  size_t written;
  int error;
  for (OptionsMap::const_iterator i = options_.begin(); i != options_.end();
       ++i) {
    res = stream.WriteAll(i->first.c_str(), i->first.length(), &written,
        &error);
    if (res != SR_SUCCESS) {
      break;
    }
    res = stream.WriteAll("=", 1, &written, &error);
    if (res != SR_SUCCESS) {
      break;
    }
    res = stream.WriteAll(i->second.c_str(), i->second.length(), &written,
        &error);
    if (res != SR_SUCCESS) {
      break;
    }
    res = stream.WriteAll("\n", 1, &written, &error);
    if (res != SR_SUCCESS) {
      break;
    }
  }
  if (res != SR_SUCCESS) {
    RTC_LOG_F(LS_ERROR) << "Unable to write to file";
    return false;
  } else {
    return true;
  }
}

bool OptionsFile::IsLegalName(const std::string &name) {
  for (size_t pos = 0; pos < name.length(); ++pos) {
    if (name[pos] == '\n' || name[pos] == '\\' || name[pos] == '=') {
      // Illegal character.
      RTC_LOG(LS_WARNING) << "Ignoring operation for illegal option " << name;
      return false;
    }
  }
  return true;
}

bool OptionsFile::IsLegalValue(const std::string &value) {
  for (size_t pos = 0; pos < value.length(); ++pos) {
    if (value[pos] == '\n' || value[pos] == '\\') {
      // Illegal character.
      RTC_LOG(LS_WARNING) << "Ignoring operation for illegal value " << value;
      return false;
    }
  }
  return true;
}

bool OptionsFile::GetStringValue(const std::string& option,
                                 std::string *out_val) const {
  RTC_LOG(LS_VERBOSE) << "OptionsFile::GetStringValue " << option;
  if (!IsLegalName(option)) {
    return false;
  }
  OptionsMap::const_iterator i = options_.find(option);
  if (i == options_.end()) {
    return false;
  }
  *out_val = i->second;
  return true;
}

bool OptionsFile::GetIntValue(const std::string& option,
                              int *out_val) const {
  RTC_LOG(LS_VERBOSE) << "OptionsFile::GetIntValue " << option;
  if (!IsLegalName(option)) {
    return false;
  }
  OptionsMap::const_iterator i = options_.find(option);
  if (i == options_.end()) {
    return false;
  }
  return FromString(i->second, out_val);
}

bool OptionsFile::SetStringValue(const std::string& option,
                                 const std::string& value) {
  RTC_LOG(LS_VERBOSE) << "OptionsFile::SetStringValue " << option << ":"
                      << value;
  if (!IsLegalName(option) || !IsLegalValue(value)) {
    return false;
  }
  options_[option] = value;
  return true;
}

bool OptionsFile::SetIntValue(const std::string& option,
                              int value) {
  RTC_LOG(LS_VERBOSE) << "OptionsFile::SetIntValue " << option << ":" << value;
  if (!IsLegalName(option)) {
    return false;
  }
  return ToString(value, &options_[option]);
}

bool OptionsFile::RemoveValue(const std::string& option) {
  RTC_LOG(LS_VERBOSE) << "OptionsFile::RemoveValue " << option;
  if (!IsLegalName(option)) {
    return false;
  }
  options_.erase(option);
  return true;
}

}  // namespace rtc
