// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(disable : 4996)
#endif

/* This executable is used for testing parser/writer using real JSON files.
 */

#include <algorithm> // sort
#include <cstdio>
#include <iostream>
#include <json/json.h>
#include <memory>
#include <sstream>

struct Options {
  Json::String path;
  Json::Features features;
  bool parseOnly;
  using writeFuncType = Json::String (*)(Json::Value const&);
  writeFuncType write;
};

static Json::String normalizeFloatingPointStr(double value) {
  char buffer[32];
  jsoncpp_snprintf(buffer, sizeof(buffer), "%.16g", value);
  buffer[sizeof(buffer) - 1] = 0;
  Json::String s(buffer);
  Json::String::size_type index = s.find_last_of("eE");
  if (index != Json::String::npos) {
    Json::String::size_type hasSign =
        (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0;
    Json::String::size_type exponentStartIndex = index + 1 + hasSign;
    Json::String normalized = s.substr(0, exponentStartIndex);
    Json::String::size_type indexDigit =
        s.find_first_not_of('0', exponentStartIndex);
    Json::String exponent = "0";
    if (indexDigit != Json::String::npos) // There is an exponent different
                                          // from 0
    {
      exponent = s.substr(indexDigit);
    }
    return normalized + exponent;
  }
  return s;
}

static Json::String readInputTestFile(const char* path) {
  FILE* file = fopen(path, "rb");
  if (!file)
    return "";
  fseek(file, 0, SEEK_END);
  auto const size = ftell(file);
  auto const usize = static_cast<size_t>(size);
  fseek(file, 0, SEEK_SET);
  auto buffer = new char[size + 1];
  buffer[size] = 0;
  Json::String text;
  if (fread(buffer, 1, usize, file) == usize)
    text = buffer;
  fclose(file);
  delete[] buffer;
  return text;
}

static void printValueTree(FILE* fout, Json::Value& value,
                           const Json::String& path = ".") {
  if (value.hasComment(Json::commentBefore)) {
    fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str());
  }
  switch (value.type()) {
  case Json::nullValue:
    fprintf(fout, "%s=null\n", path.c_str());
    break;
  case Json::intValue:
    fprintf(fout, "%s=%s\n", path.c_str(),
            Json::valueToString(value.asLargestInt()).c_str());
    break;
  case Json::uintValue:
    fprintf(fout, "%s=%s\n", path.c_str(),
            Json::valueToString(value.asLargestUInt()).c_str());
    break;
  case Json::realValue:
    fprintf(fout, "%s=%s\n", path.c_str(),
            normalizeFloatingPointStr(value.asDouble()).c_str());
    break;
  case Json::stringValue:
    fprintf(fout, "%s=\"%s\"\n", path.c_str(), value.asString().c_str());
    break;
  case Json::booleanValue:
    fprintf(fout, "%s=%s\n", path.c_str(), value.asBool() ? "true" : "false");
    break;
  case Json::arrayValue: {
    fprintf(fout, "%s=[]\n", path.c_str());
    Json::ArrayIndex size = value.size();
    for (Json::ArrayIndex index = 0; index < size; ++index) {
      static char buffer[16];
      jsoncpp_snprintf(buffer, sizeof(buffer), "[%u]", index);
      printValueTree(fout, value[index], path + buffer);
    }
  } break;
  case Json::objectValue: {
    fprintf(fout, "%s={}\n", path.c_str());
    Json::Value::Members members(value.getMemberNames());
    std::sort(members.begin(), members.end());
    Json::String suffix = *(path.end() - 1) == '.' ? "" : ".";
    for (const auto& name : members) {
      printValueTree(fout, value[name], path + suffix + name);
    }
  } break;
  default:
    break;
  }

  if (value.hasComment(Json::commentAfter)) {
    fprintf(fout, "%s\n", value.getComment(Json::commentAfter).c_str());
  }
}

static int parseAndSaveValueTree(const Json::String& input,
                                 const Json::String& actual,
                                 const Json::String& kind,
                                 const Json::Features& features, bool parseOnly,
                                 Json::Value* root, bool use_legacy) {
  if (!use_legacy) {
    Json::CharReaderBuilder builder;

    builder.settings_["allowComments"] = features.allowComments_;
    builder.settings_["strictRoot"] = features.strictRoot_;
    builder.settings_["allowDroppedNullPlaceholders"] =
        features.allowDroppedNullPlaceholders_;
    builder.settings_["allowNumericKeys"] = features.allowNumericKeys_;

    std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    Json::String errors;
    const bool parsingSuccessful =
        reader->parse(input.data(), input.data() + input.size(), root, &errors);

    if (!parsingSuccessful) {
      std::cerr << "Failed to parse " << kind << " file: " << std::endl
                << errors << std::endl;
      return 1;
    }

    // We may instead check the legacy implementation (to ensure it doesn't
    // randomly get broken).
  } else {
    Json::Reader reader(features);
    const bool parsingSuccessful =
        reader.parse(input.data(), input.data() + input.size(), *root);
    if (!parsingSuccessful) {
      std::cerr << "Failed to parse " << kind << " file: " << std::endl
                << reader.getFormatedErrorMessages() << std::endl;
      return 1;
    }
  }

  if (!parseOnly) {
    FILE* factual = fopen(actual.c_str(), "wt");
    if (!factual) {
      std::cerr << "Failed to create '" << kind << "' actual file."
                << std::endl;
      return 2;
    }
    printValueTree(factual, *root);
    fclose(factual);
  }
  return 0;
}
// static Json::String useFastWriter(Json::Value const& root) {
//   Json::FastWriter writer;
//   writer.enableYAMLCompatibility();
//   return writer.write(root);
// }
static Json::String useStyledWriter(Json::Value const& root) {
  Json::StyledWriter writer;
  return writer.write(root);
}
static Json::String useStyledStreamWriter(Json::Value const& root) {
  Json::StyledStreamWriter writer;
  Json::OStringStream sout;
  writer.write(sout, root);
  return sout.str();
}
static Json::String useBuiltStyledStreamWriter(Json::Value const& root) {
  Json::StreamWriterBuilder builder;
  return Json::writeString(builder, root);
}
static int rewriteValueTree(const Json::String& rewritePath,
                            const Json::Value& root,
                            Options::writeFuncType write,
                            Json::String* rewrite) {
  *rewrite = write(root);
  FILE* fout = fopen(rewritePath.c_str(), "wt");
  if (!fout) {
    std::cerr << "Failed to create rewrite file: " << rewritePath << std::endl;
    return 2;
  }
  fprintf(fout, "%s\n", rewrite->c_str());
  fclose(fout);
  return 0;
}

static Json::String removeSuffix(const Json::String& path,
                                 const Json::String& extension) {
  if (extension.length() >= path.length())
    return Json::String("");
  Json::String suffix = path.substr(path.length() - extension.length());
  if (suffix != extension)
    return Json::String("");
  return path.substr(0, path.length() - extension.length());
}

static void printConfig() {
// Print the configuration used to compile JsonCpp
#if defined(JSON_NO_INT64)
  std::cout << "JSON_NO_INT64=1" << std::endl;
#else
  std::cout << "JSON_NO_INT64=0" << std::endl;
#endif
}

static int printUsage(const char* argv[]) {
  std::cout << "Usage: " << argv[0] << " [--strict] input-json-file"
            << std::endl;
  return 3;
}

static int parseCommandLine(int argc, const char* argv[], Options* opts) {
  opts->parseOnly = false;
  opts->write = &useStyledWriter;
  if (argc < 2) {
    return printUsage(argv);
  }
  int index = 1;
  if (Json::String(argv[index]) == "--parse-only") {
    opts->parseOnly = true;
    ++index;
  }
  if (Json::String(argv[index]) == "--strict") {
    opts->features = Json::Features::strictMode();
    ++index;
  }
  if (Json::String(argv[index]) == "--json-config") {
    printConfig();
    return 3;
  }
  if (Json::String(argv[index]) == "--json-writer") {
    ++index;
    Json::String const writerName(argv[index++]);
    if (writerName == "StyledWriter") {
      opts->write = &useStyledWriter;
    } else if (writerName == "StyledStreamWriter") {
      opts->write = &useStyledStreamWriter;
    } else if (writerName == "BuiltStyledStreamWriter") {
      opts->write = &useBuiltStyledStreamWriter;
    } else {
      std::cerr << "Unknown '--json-writer' " << writerName << std::endl;
      return 4;
    }
  }
  if (index == argc || index + 1 < argc) {
    return printUsage(argv);
  }
  opts->path = argv[index];
  return 0;
}

static int runTest(Options const& opts, bool use_legacy) {
  int exitCode = 0;

  Json::String input = readInputTestFile(opts.path.c_str());
  if (input.empty()) {
    std::cerr << "Invalid input file: " << opts.path << std::endl;
    return 3;
  }

  Json::String basePath = removeSuffix(opts.path, ".json");
  if (!opts.parseOnly && basePath.empty()) {
    std::cerr << "Bad input path '" << opts.path
              << "'. Must end with '.expected'" << std::endl;
    return 3;
  }

  Json::String const actualPath = basePath + ".actual";
  Json::String const rewritePath = basePath + ".rewrite";
  Json::String const rewriteActualPath = basePath + ".actual-rewrite";

  Json::Value root;
  exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features,
                                   opts.parseOnly, &root, use_legacy);
  if (exitCode || opts.parseOnly) {
    return exitCode;
  }

  Json::String rewrite;
  exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite);
  if (exitCode) {
    return exitCode;
  }

  Json::Value rewriteRoot;
  exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite",
                                   opts.features, opts.parseOnly, &rewriteRoot,
                                   use_legacy);

  return exitCode;
}

int main(int argc, const char* argv[]) {
  Options opts;
  try {
    int exitCode = parseCommandLine(argc, argv, &opts);
    if (exitCode != 0) {
      std::cerr << "Failed to parse command-line." << std::endl;
      return exitCode;
    }

    const int modern_return_code = runTest(opts, false);
    if (modern_return_code) {
      return modern_return_code;
    }

    const std::string filename =
        opts.path.substr(opts.path.find_last_of("\\/") + 1);
    const bool should_run_legacy = (filename.rfind("legacy_", 0) == 0);
    if (should_run_legacy) {
      return runTest(opts, true);
    }
  } catch (const std::exception& e) {
    std::cerr << "Unhandled exception:" << std::endl << e.what() << std::endl;
    return 1;
  }
  return 0;
}

#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
