// Copyright 2024 The Bazel Authors. All rights reserved.
//
// Licensed 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.

#ifndef BAZEL_TOOLS_CPP_MODULE_TOOLS_COMMON_HSON_HPP_
#define BAZEL_TOOLS_CPP_MODULE_TOOLS_COMMON_HSON_HPP_

#include <algorithm>
#include <any>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <variant>
#include <vector>
// forward decl
struct JsonValue;
inline std::string to_json(const JsonValue &data);

// Define a basic struct for JSON values
struct JsonValue {
  using ObjectType = std::map<std::string, JsonValue>;
  using ArrayType = std::vector<JsonValue>;

  std::variant<std::string, bool, long, double, ObjectType, ArrayType,
               std::nullptr_t>
      value;

  JsonValue() : value(nullptr) {}
  JsonValue(const std::string &v) : value(v) {}
  JsonValue(const char *v) : value(std::string(v)) {}
  JsonValue(bool v) : value(v) {}
  JsonValue(long v) : value(v) {}
  JsonValue(int v) : value((long)v) {}
  JsonValue(double v) : value(v) {}
  JsonValue(const ObjectType &v) : value(v) {}
  JsonValue(const ArrayType &v) : value(v) {}
  JsonValue(std::nullptr_t) : value(nullptr) {}

  bool is_null() const { return std::holds_alternative<std::nullptr_t>(value); }
  bool is_string() const { return std::holds_alternative<std::string>(value); }
  bool is_object() const { return std::holds_alternative<ObjectType>(value); }
  bool is_array() const { return std::holds_alternative<ArrayType>(value); }
  bool is_bool() const { return std::holds_alternative<bool>(value); }
  bool is_long() const { return std::holds_alternative<long>(value); }
  bool is_double() const { return std::holds_alternative<double>(value); }

  const std::string &as_string() const { return std::get<std::string>(value); }
  const ObjectType &as_object() const { return std::get<ObjectType>(value); }
  const ArrayType &as_array() const { return std::get<ArrayType>(value); }
  bool as_bool() const { return std::get<bool>(value); }
  long as_long() const { return std::get<long>(value); }
  double as_double() const { return std::get<double>(value); }

  // Implement equality operator
  bool operator==(const JsonValue &other) const {
    if (value.index() != other.value.index()) return false;

    if (is_null()) return true;
    if (is_string()) return as_string() == other.as_string();
    if (is_bool()) return as_bool() == other.as_bool();
    if (is_long()) return as_long() == other.as_long();
    if (is_double()) return as_double() == other.as_double();
    if (is_object()) return as_object() == other.as_object();
    if (is_array()) return as_array() == other.as_array();

    return false;
  }

  bool operator!=(const JsonValue &other) const { return !(*this == other); }

  std::string dump() const { return to_json(*this); }
};

// Define the JSON parser class
class Json {
 public:
  // Singleton instance
  static Json &instance() {
    static Json INSTANCE;
    return INSTANCE;
  }

  // Function to encode an object to JSON
  std::string encode(const JsonValue &x) const {
    Encoder enc;
    try {
      enc.encode(x);
    } catch (const std::overflow_error &e) {
      throw std::runtime_error("nesting depth limit exceeded");
    }
    return enc.out.str();
  }

  // Function to decode a JSON string to an object
  JsonValue decode(const std::string &x) const {
    try {
      return Decoder(x).decode();
    } catch (const std::runtime_error &e) {
      throw std::runtime_error("Invalid JSON string");
    }
  }

 private:
  Json() {}

  // Encoder class to serialize objects to JSON
  class Encoder {
   public:
    void encode(const JsonValue &x) {
      if (x.is_null()) {
        out << "null";
        return;
      }
      if (x.is_string()) {
        append_quoted(x.as_string());
        return;
      }
      if (x.is_bool()) {
        out << std::boolalpha << x.as_bool();
        return;
      }
      if (x.is_long()) {
        out << x.as_long();
        return;
      }
      if (x.is_double()) {
        double d = x.as_double();
        if (!std::isfinite(d)) {
          throw std::runtime_error("Cannot encode non-finite float");
        }
        out << std::setprecision(std::numeric_limits<double>::digits10) << d;
        return;
      }
      if (x.is_object()) {
        const auto &m = x.as_object();
        out << '{';
        std::string sep = "";
        for (const auto &item : m) {
          out << sep;
          sep = ",";
          append_quoted(item.first);
          out << ':';
          encode(item.second);
        }
        out << '}';
        return;
      }
      if (x.is_array()) {
        const auto &v = x.as_array();
        out << '[';
        std::string sep = "";
        for (const auto &value : v) {
          out << sep;
          sep = ",";
          encode(value);
        }
        out << ']';
        return;
      }
      // Add more cases for other types as needed
      throw std::runtime_error("Cannot encode value as JSON");
    }

    std::ostringstream out;

   private:
    void append_quoted(const std::string &s) {
      out << '"';
      for (char c : s) {
        switch (c) {
          case '"':
            out << "\\\"";
            break;
          case '\\':
            out << "\\\\";
            break;
          case '\b':
            out << "\\b";
            break;
          case '\f':
            out << "\\f";
            break;
          case '\n':
            out << "\\n";
            break;
          case '\r':
            out << "\\r";
            break;
          case '\t':
            out << "\\t";
            break;
          default:
            if ('\x00' <= c && c <= '\x1f') {
              out << "\\u" << std::hex << std::setw(4) << std::setfill('0')
                  << static_cast<long>(c);
            } else {
              out << c;
            }
        }
      }
      out << '"';
    }
  };

  // Decoder class to parse JSON strings to objects
  class Decoder {
   public:
    Decoder(const std::string &s) : s(s), i(0) {}

    JsonValue decode() {
      auto x = parse();
      if (skip_space()) {
        throw std::runtime_error("Unexpected character after value");
      }
      return x;
    }

   private:
    std::string s;
    size_t i;

    JsonValue parse() {
      char c = next();
      switch (c) {
        case '"':
          return parse_string();
        case 'n':
          if (s.substr(i, 4) == "null") {
            i += 4;
            return nullptr;
          }
          break;
        case 't':
          if (s.substr(i, 4) == "true") {
            i += 4;
            return true;
          }
          break;
        case 'f':
          if (s.substr(i, 5) == "false") {
            i += 5;
            return false;
          }
          break;
        case '[':
          return parse_array();
        case '{':
          return parse_object();
        default:
          if (isdigit(c) || c == '-') {
            return parse_number(c);
          }
      }
      throw std::runtime_error("Unexpected character");
    }

    JsonValue parse_string() {
      i++;  // skip "
      std::ostringstream str;
      while (i < s.size()) {
        char c = s[i++];
        if (c == '"') return str.str();
        if (c == '\\') {
          c = s[i++];
          switch (c) {
            case 'b':
              str << '\b';
              break;
            case 'f':
              str << '\f';
              break;
            case 'n':
              str << '\n';
              break;
            case 'r':
              str << '\r';
              break;
            case 't':
              str << '\t';
              break;
            case 'u':
              // Handle \uXXXX
              str << static_cast<char>(std::stoi(s.substr(i, 4), nullptr, 16));
              i += 4;
              break;
            default:
              str << c;
          }
        } else {
          str << c;
        }
      }
      throw std::runtime_error("Unclosed string literal");
    }

    JsonValue parse_array() {
      JsonValue::ArrayType array;
      i++;  // skip [
      if (next() != ']') {
        while (true) {
          array.push_back(parse());
          char c = next();
          if (c != ',') {
            if (c != ']') throw std::runtime_error("Expected ',' or ']'");
            break;
          }
          i++;  // skip ,
        }
      }
      i++;  // skip ]
      return array;
    }

    JsonValue parse_object() {
      JsonValue::ObjectType object;
      i++;  // skip {
      if (next() != '}') {
        while (true) {
          std::string key = std::get<std::string>(parse().value);
          if (next() != ':') throw std::runtime_error("Expected ':'");
          i++;  // skip :
          object[key] = parse();
          char c = next();
          if (c != ',') {
            if (c != '}') throw std::runtime_error("Expected ',' or '}'");
            break;
          }
          i++;  // skip ,
        }
      }
      i++;  // skip }
      return object;
    }

    JsonValue parse_number(char c) {
      size_t j = i + 1;
      bool isfloat = false;
      while (j < s.size()) {
        c = s[j];
        if (isdigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' ||
            c == 'E') {
          if (c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-')
            isfloat = true;
          j++;
        } else {
          break;
        }
      }
      std::string num = s.substr(i, j - i);
      i = j;
      std::istringstream iss(num);
      if (isfloat) {
        double d;
        iss >> d;
        return d;
      } else {
        long n;
        iss >> n;
        return n;
      }
    }

    bool skip_space() {
      while (i < s.size() && isspace(s[i])) {
        i++;
      }
      return i < s.size();
    }

    char next() {
      if (skip_space()) {
        return s[i];
      }
      throw std::runtime_error("Unexpected end of input");
    }
  };
};

inline JsonValue parse_json(const std::string &data) {
  Json &json = Json::instance();
  return json.decode(data);
}

inline std::string to_json(const JsonValue &data) {
  Json &json = Json::instance();
  return json.encode(data);
}

#endif  //BAZEL_TOOLS_CPP_MODULE_TOOLS_COMMON_HSON_HPP_
