// Copyright 2007-2010 Baptiste Lepilleur
// 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

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

#include <json/json.h>
#include <algorithm> // sort
#include <stdio.h>

#if defined(_MSC_VER) && _MSC_VER >= 1310
#pragma warning(disable : 4996) // disable fopen deprecation warning
#endif

static std::string normalizeFloatingPointStr(double value) {
  char buffer[32];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
  sprintf_s(buffer, sizeof(buffer), "%.16g", value);
#else
  snprintf(buffer, sizeof(buffer), "%.16g", value);
#endif
  buffer[sizeof(buffer) - 1] = 0;
  std::string s(buffer);
  std::string::size_type index = s.find_last_of("eE");
  if (index != std::string::npos) {
    std::string::size_type hasSign =
        (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0;
    std::string::size_type exponentStartIndex = index + 1 + hasSign;
    std::string normalized = s.substr(0, exponentStartIndex);
    std::string::size_type indexDigit =
        s.find_first_not_of('0', exponentStartIndex);
    std::string exponent = "0";
    if (indexDigit !=
        std::string::npos) // There is an exponent different from 0
    {
      exponent = s.substr(indexDigit);
    }
    return normalized + exponent;
  }
  return s;
}

static std::string readInputTestFile(const char* path) {
  FILE* file = fopen(path, "rb");
  if (!file)
    return std::string("");
  fseek(file, 0, SEEK_END);
  long size = ftell(file);
  fseek(file, 0, SEEK_SET);
  std::string text;
  char* buffer = new char[size + 1];
  buffer[size] = 0;
  if (fread(buffer, 1, size, file) == (unsigned long)size)
    text = buffer;
  fclose(file);
  delete[] buffer;
  return text;
}

static void
printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") {
  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());
    int size = value.size();
    for (int index = 0; index < size; ++index) {
      static char buffer[16];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
      sprintf_s(buffer, sizeof(buffer), "[%d]", index);
#else
      snprintf(buffer, sizeof(buffer), "[%d]", index);
#endif
      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());
    std::string suffix = *(path.end() - 1) == '.' ? "" : ".";
    for (Json::Value::Members::iterator it = members.begin();
         it != members.end();
         ++it) {
      const std::string& name = *it;
      printValueTree(fout, value[name], path + suffix + name);
    }
  } break;
  default:
    break;
  }
}

static int parseAndSaveValueTree(const std::string& input,
                                 const std::string& actual,
                                 const std::string& kind,
                                 Json::Value& root,
                                 const Json::Features& features,
                                 bool parseOnly) {
  Json::Reader reader(features);
  bool parsingSuccessful = reader.parse(input, root);
  if (!parsingSuccessful) {
    printf("Failed to parse %s file: \n%s\n",
           kind.c_str(),
           reader.getFormattedErrorMessages().c_str());
    return 1;
  }

  if (!parseOnly) {
    FILE* factual = fopen(actual.c_str(), "wt");
    if (!factual) {
      printf("Failed to create %s actual file.\n", kind.c_str());
      return 2;
    }
    printValueTree(factual, root);
    fclose(factual);
  }
  return 0;
}

static int rewriteValueTree(const std::string& rewritePath,
                            const Json::Value& root,
                            std::string& rewrite) {
  // Json::FastWriter writer;
  // writer.enableYAMLCompatibility();
  Json::StyledWriter writer;
  rewrite = writer.write(root);
  FILE* fout = fopen(rewritePath.c_str(), "wt");
  if (!fout) {
    printf("Failed to create rewrite file: %s\n", rewritePath.c_str());
    return 2;
  }
  fprintf(fout, "%s\n", rewrite.c_str());
  fclose(fout);
  return 0;
}

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

static void printConfig() {
// Print the configuration used to compile JsonCpp
#if defined(JSON_NO_INT64)
  printf("JSON_NO_INT64=1\n");
#else
  printf("JSON_NO_INT64=0\n");
#endif
}

static int printUsage(const char* argv[]) {
  printf("Usage: %s [--strict] input-json-file", argv[0]);
  return 3;
}

int parseCommandLine(int argc,
                     const char* argv[],
                     Json::Features& features,
                     std::string& path,
                     bool& parseOnly) {
  parseOnly = false;
  if (argc < 2) {
    return printUsage(argv);
  }

  int index = 1;
  if (std::string(argv[1]) == "--json-checker") {
    features = Json::Features::strictMode();
    parseOnly = true;
    ++index;
  }

  if (std::string(argv[1]) == "--json-config") {
    printConfig();
    return 3;
  }

  if (index == argc || index + 1 < argc) {
    return printUsage(argv);
  }

  path = argv[index];
  return 0;
}

int main(int argc, const char* argv[]) {
  std::string path;
  Json::Features features;
  bool parseOnly;
  int exitCode = parseCommandLine(argc, argv, features, path, parseOnly);
  if (exitCode != 0) {
    return exitCode;
  }

  try {
    std::string input = readInputTestFile(path.c_str());
    if (input.empty()) {
      printf("Failed to read input or empty input: %s\n", path.c_str());
      return 3;
    }

    std::string basePath = removeSuffix(argv[1], ".json");
    if (!parseOnly && basePath.empty()) {
      printf("Bad input path. Path does not end with '.expected':\n%s\n",
             path.c_str());
      return 3;
    }

    std::string actualPath = basePath + ".actual";
    std::string rewritePath = basePath + ".rewrite";
    std::string rewriteActualPath = basePath + ".actual-rewrite";

    Json::Value root;
    exitCode = parseAndSaveValueTree(
        input, actualPath, "input", root, features, parseOnly);
    if (exitCode == 0 && !parseOnly) {
      std::string rewrite;
      exitCode = rewriteValueTree(rewritePath, root, rewrite);
      if (exitCode == 0) {
        Json::Value rewriteRoot;
        exitCode = parseAndSaveValueTree(rewrite,
                                         rewriteActualPath,
                                         "rewrite",
                                         rewriteRoot,
                                         features,
                                         parseOnly);
      }
    }
  }
  catch (const std::exception& e) {
    printf("Unhandled exception:\n%s\n", e.what());
    exitCode = 1;
  }

  return exitCode;
}
