/*
 * 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 <geode/Properties.hpp>
#include <geode/GeodeTypeIds.hpp>
#include <geode/CacheableKey.hpp>
#include <geode/CacheableString.hpp>
#include <geode/ExceptionTypes.hpp>
#include <geode/DataOutput.hpp>
#include <geode/DataInput.hpp>

namespace apache {
namespace geode {
namespace client {

class PropertiesFile {
  Properties& m_props;
  std::string m_fileName;

 public:
  explicit PropertiesFile(Properties& props);

  void parseLine(const std::string& line);
  void readFile(const std::string& fileName);
  char* nextBufferLine(char** cursor, char* bufbegin, size_t totalLen);
};

std::shared_ptr<Properties> Properties::create() {
  return std::make_shared<Properties>();
}

std::shared_ptr<CacheableString> Properties::find(const std::string& key) {
  return std::dynamic_pointer_cast<CacheableString>(
      this->find(CacheableString::create(key)));
}

std::shared_ptr<Cacheable> Properties::find(
    const std::shared_ptr<CacheableKey>& key) {
  if (!key) {
    throw NullPointerException("Properties::find: Null key given.");
  }

  auto entry = m_map.find(key);
  if (entry != m_map.end()) {
    return entry->second;
  }

  return nullptr;
}

void Properties::insert(std::string key, std::string value) {
  this->insert(CacheableString::create(std::move(key)),
               CacheableString::create(std::move(value)));
}

void Properties::insert(std::string key, const int value) {
  this->insert(CacheableString::create(std::move(key)),
               CacheableString::create(std::to_string(value)));
}

void Properties::insert(const std::shared_ptr<CacheableKey>& key,
                        const std::shared_ptr<Cacheable>& value) {
  if (!key) {
    throw NullPointerException("Properties::insert: Null key given.");
  }

  m_map[key] = value;
}

void Properties::remove(const std::string& key) {
  this->remove(CacheableString::create(key));
}

void Properties::remove(const std::shared_ptr<CacheableKey>& key) {
  m_map.erase(key);
}

size_t Properties::getSize() const {
  return m_map.size();
}

void Properties::foreach (Visitor& visitor) const {
  for (auto& entry : m_map) {
    visitor.visit(entry.first, entry.second);
  }
}

void Properties::addAll(const std::shared_ptr<Properties>& other) {
  if (other == nullptr) return;

  for (auto& entry : other->m_map) {
    m_map[entry.first] = entry.second;
  }
}

void Properties::load(const std::string& fileName) {
  PropertiesFile pf(*this);
  pf.readFile(fileName);
}

PropertiesFile::PropertiesFile(Properties& props) : m_props(props) {}

void PropertiesFile::readFile(const std::string& fileName) {
  char buf[8192];
  FILE* fp = fopen(fileName.c_str(), "r");
  if (fp != nullptr) {
    size_t len = 0;
    while ((len = fread(buf, 1, 8192, fp)) != 0) {
      /* adongre
       * CID 28894: String not null terminated (STRING_NULL)
       * Function "fread" does not terminate string "*buf".
       */
      buf[len] = '\0';
      char* tmp = buf;
      char* line = 0;
      while ((line = nextBufferLine(&tmp, buf, len)) != nullptr) {
        parseLine(line);
      }
    }
    fclose(fp);
  }
}

char* PropertiesFile::nextBufferLine(char** cursor, char* bufbegin,
                                     size_t totalLen) {
  if (static_cast<size_t>((*cursor) - bufbegin) >= totalLen) {
    return 0;
  }

  char* lineBegin = *cursor;
  while (((**cursor) != 10) && ((**cursor) != 13) &&
         (static_cast<size_t>((*cursor) - bufbegin) < totalLen)) {
    (*cursor)++;
  }
  **cursor = '\0';
  (*cursor)++;  // move to begin of next line.
  return lineBegin;
}

void PropertiesFile::parseLine(const std::string& line) {
  if (line.c_str()[0] == '#') {
    return;
  }
  if (line.c_str()[0] == '/') {
    return;
  }

  char key[1024];
  char value[1024];
  int res = sscanf(line.c_str(), "%[^ \t=]%*[ \t=]%[^\n\r]", key, value);
  if (res != 2) {
    // bad parse...
    return;
  }
  // clean up value from trailing whitespace.
  size_t len = strlen(value);
  size_t end = len - 1;
  while (end > 0) {
    if (value[end] != ' ') {
      break;
    }
    value[end] = '\0';
    end--;
  }
  // clean up escape '\' sequences.
  // size_t idx = 0;
  // size_t widx = 0;
  // len = strlen( value );
  // while( idx < (len + 1 /* copy the Null terminator also */ ) ) {
  //  if ( value[idx] == '\\' ) {
  //    idx++;
  //  }
  //  value[widx] = value[idx];
  //  widx++;
  //  idx++;
  //}

  m_props.insert(key, value);
}

std::shared_ptr<Serializable> Properties::createDeserializable() {
  return std::make_shared<Properties>();
}

int8_t Properties::getDsCode() const { return GeodeTypeIds::Properties; }

void Properties::toData(DataOutput& output) const {
  output.writeArrayLen(static_cast<uint32_t>(m_map.size()));
  for (auto& entry : m_map) {
    output.writeObject(entry.first);
    output.writeObject(entry.second);
  }
}

void Properties::fromData(DataInput& input) {
  auto mapSize = input.readArrayLength();
  m_map.reserve(mapSize);

  for (int i = 0; i < mapSize; i++) {
    auto key = std::dynamic_pointer_cast<CacheableKey>(input.readObject());
    auto value = std::dynamic_pointer_cast<Cacheable>(input.readObject());
    m_map.emplace(key, value);
  }
}

}  // namespace client
}  // namespace geode
}  // namespace apache
