// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "lib/json/json_parser.h"

#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <functional>
#include <string>

#include <lib/fit/function.h>
#include "lib/fxl/files/file.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/strings/join_strings.h"
#include "lib/fxl/strings/string_printf.h"
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"

namespace json {
namespace {

using ErrorCallback = std::function<void(size_t, const std::string&)>;
using fxl::StringPrintf;

void GetLineAndColumnForOffset(const std::string& input, size_t offset,
                               int32_t* output_line, int32_t* output_column) {
  if (offset == 0) {
    // Errors at position 0 are assumed to be related to the whole file.
    *output_line = 0;
    *output_column = 0;
    return;
  }
  *output_line = 1;
  *output_column = 1;
  for (size_t i = 0; i < input.size() && i < offset; i++) {
    if (input[i] == '\n') {
      *output_line += 1;
      *output_column = 1;
    } else {
      *output_column += 1;
    }
  }
}
}  // namespace

rapidjson::Document JSONParser::ParseFromFile(const std::string& file) {
  file_ = file;
  std::string data;
  if (!files::ReadFileToString(file, &data)) {
    errors_.push_back(StringPrintf("Failed to read file: %s", file.c_str()));
    return rapidjson::Document();
  }
  return ParseFromString(data, file);
}

rapidjson::Document JSONParser::ParseFromFileAt(int dirfd,
                                                const std::string& file) {
  file_ = file;
  std::string data;
  if (!files::ReadFileToStringAt(dirfd, file, &data)) {
    errors_.push_back(StringPrintf("Failed to read file: %s", file.c_str()));
    return rapidjson::Document();
  }
  return ParseFromString(data, file);
}

rapidjson::Document JSONParser::ParseFromString(const std::string& data,
                                                const std::string& file) {
  data_ = data;
  file_ = file;
  rapidjson::Document document;
  document.Parse(data_);
  if (document.HasParseError()) {
    ReportErrorInternal(document.GetErrorOffset(),
                        GetParseError_En(document.GetParseError()));
  }
  return document;
}

void JSONParser::ParseFromDirectory(
    const std::string& path, fit::function<void(rapidjson::Document)> cb) {
  static constexpr char kPathTooLong[] =
      "Config directory path is too long: %s";
  char buf[PATH_MAX];
  buf[0] = '\0';
  if (strlcpy(buf, path.c_str(), PATH_MAX) >= PATH_MAX) {
    file_ = path;
    ReportError(fxl::StringPrintf(kPathTooLong, buf));
    return;
  }
  if (buf[strlen(buf) - 2] != '/' && strlcat(buf, "/", PATH_MAX) >= PATH_MAX) {
    file_ = path;
    ReportError(fxl::StringPrintf(kPathTooLong, buf));
    return;
  }
  const size_t dir_len = strlen(buf);
  DIR* cfg_dir = opendir(path.c_str());
  if (cfg_dir != nullptr) {
    for (dirent* cfg = readdir(cfg_dir); cfg != nullptr;
         cfg = readdir(cfg_dir)) {
      if (strcmp(".", cfg->d_name) == 0 || strcmp("..", cfg->d_name) == 0) {
        continue;
      }
      if (strlcat(buf, cfg->d_name, PATH_MAX) >= PATH_MAX) {
        file_ = path;
        ReportError(fxl::StringPrintf(kPathTooLong, buf));
        continue;
      }
      rapidjson::Document document = ParseFromFile(buf);
      if (!document.HasParseError() && !document.IsNull()) {
        cb(std::move(document));
      }
      // Reset buf to directory path.
      buf[dir_len] = '\0';
    }
    closedir(cfg_dir);
  } else {
    file_ = path;
    ReportError("Could not open config directory.");
  }
}

void JSONParser::ReportError(const std::string& error) {
  ReportErrorInternal(0, error);
}

void JSONParser::ReportErrorInternal(size_t offset, const std::string& error) {
  int32_t line;
  int32_t column;
  GetLineAndColumnForOffset(data_, offset, &line, &column);
  if (line == 0) {
    errors_.push_back(StringPrintf("%s: %s", file_.c_str(), error.c_str()));
  } else {
    errors_.push_back(StringPrintf("%s:%d:%d: %s", file_.c_str(), line, column,
                                   error.c_str()));
  }
}

bool JSONParser::HasError() const { return !errors_.empty(); }

std::string JSONParser::error_str() const {
  return fxl::JoinStrings(errors_, "\n");
}

}  // namespace json
