// Copyright 2021 The Verible Authors.
//
// 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.

// A simple code generator taking a yaml file and generating nlohmann/json
// serializable structs.

#include <cstdio>
#include <fstream>
#include <iostream>
#include <memory>
#include <regex>
#include <string>
#include <unordered_map>

#include "absl/container/flat_hash_map.h"
#include "absl/flags/flag.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "common/util/init_command_line.h"

ABSL_FLAG(std::string, output, "",
          "Name of the output file. If empty, output is written to stdout");
ABSL_FLAG(std::string, class_namespace, "",
          "Namespace of the generated structs");
ABSL_FLAG(std::string, json_header, "<nlohmann/json.hpp>",
          "Include path to json.hpp including brackets <> or quotes \"\" "
          "around.");

// Interface. Currently private, but could be moved to a header if needed.
struct Location {
  const char *filename;
  int line;
};
inline std::ostream &operator<<(std::ostream &out, const Location &loc) {
  return out << loc.filename << ":" << loc.line << ": ";
}

struct ObjectType;

struct Property {
  Property(const Location &loc, ObjectType *owner, const std::string &name,
           bool is_optional, bool is_array)
      : location(loc),
        owner(owner),
        name(name),
        is_optional(is_optional),
        is_array(is_array) {}

  bool EqualNameValue(const Property &other) const {
    return other.name == name;
  }

  Location location = {"<>", 0};  // Where it is defined
  ObjectType *owner;

  std::string name;
  bool is_optional;
  bool is_array;
  std::string default_value;

  // TODO: have alternative types
  std::string type;
  ObjectType *object_type = nullptr;
};

struct ObjectType {
  ObjectType(const Location &loc, const std::string &name)
      : location(loc), name(name) {}

  Location location;
  std::string name;

  std::vector<std::string> extends;  // name of the superclasses
  std::vector<Property> properties;

  std::vector<const ObjectType *> superclasses;  // fixed up after all read.
};

using ObjectTypeVector = std::vector<ObjectType *>;

static bool contains(const std::string &s, char c) {
  return absl::StrContains(s, c);
}

// Returns if successful.
static bool ParseObjectTypesFromFile(const std::string &filename,
                                     ObjectTypeVector *parsed_out) {
  static const std::regex emptyline_or_comment_re("^[ \t]*(#.*)?");
  static const std::regex toplevel_object_re("^([a-zA-Z0-9_]+):");

  // For now, let's just read up to the first type and leave out alternatives
  static const std::regex property_re(
      "^[ \t]+([a-zA-Z_<]+)([\\?\\+]*):[ ]*([a-zA-Z0-9_]+)[ ]*(=[ \t]*(.+))?");

  Location current_location = {filename.c_str(), 0};
  ObjectType *current_model = nullptr;
  std::ifstream in(filename);
  if (!in.good()) {
    std::cerr << "Can't open " << filename << "\n";
    return false;
  }
  std::string line;
  std::smatch matches;
  while (!in.eof()) {
    std::getline(in, line);
    current_location.line++;

    if (std::regex_match(line, emptyline_or_comment_re)) continue;

    if (std::regex_search(line, matches, toplevel_object_re)) {
      current_model = new ObjectType(current_location, matches[1]);
      parsed_out->push_back(current_model);
      continue;
    }

    if (!current_model) {
      std::cerr << current_location << "No ObjectType definition\n";
      return false;
    }
    if (!std::regex_search(line, matches, property_re)) {
      std::cerr << current_location << "This doesn't look like a property\n";
      return false;
    }

    if (matches[1] == "<") {
      current_model->extends.push_back(matches[3]);
      continue;
    }

    Property property(current_location, current_model, matches[1],
                      contains(matches[2], '?'), contains(matches[2], '+'));
    property.type = matches[3];  // TODO: allow multiple
    property.default_value = matches[5];
    current_model->properties.push_back(property);
  }
  return true;
}

// Validate types and return if successful.
static bool ValidateTypes(ObjectTypeVector *object_types) {
  absl::flat_hash_map<std::string, ObjectType *> typeByName;

  for (auto &obj : *object_types) {
    // We only insert types as they come, so that we can make sure they are
    // used after being defined.
    auto inserted = typeByName.insert({obj->name, obj});
    if (!inserted.second) {
      std::cerr << obj->location << "Duplicate name; previous defined in "
                << inserted.first->second->location << "\n";
      return false;
    }

    // Resolve superclasses
    for (const auto &e : obj->extends) {
      const auto &found = typeByName.find(e);
      if (found == typeByName.end()) {
        std::cerr << obj->location << "Unknown superclass " << e << "\n";
        return false;
      }
      obj->superclasses.push_back(found->second);
    }

    for (auto &p : obj->properties) {
      const std::string &t = p.type;
      if (t == "object" || t == "string" || t == "integer" || t == "boolean") {
        continue;
      }

      const auto &found = typeByName.find(t);
      if (found == typeByName.end()) {
        std::cerr << p.location << "Unknown object type '" << t << "'\n";
        return false;
      }
      p.object_type = found->second;
    }

    // Validate that we don't have properties with the same name twice in
    // one class (including superclasses)
    absl::flat_hash_map<std::string, const Property *> my_property_names;
    for (const auto &p : obj->properties) {
      auto inserted = my_property_names.insert({p.name, &p});
      if (inserted.second) continue;
      std::cerr << p.location << "In class '" << obj->name
                << "' same name property '" << p.name << "' defined here\n"
                << inserted.first->second->location << "  ... and here\n";
      return false;
    }
    for (const auto &s : obj->superclasses) {
      for (const auto &sp : s->properties) {
        auto inserted = my_property_names.insert({sp.name, &sp});
        if (inserted.second) continue;
        const bool is_owner_superclass = (inserted.first->second->owner != obj);
        std::cerr << obj->location << obj->name << " has duplicate property '"
                  << sp.name << "'\n"
                  << inserted.first->second->location << "  ... found in "
                  << (is_owner_superclass ? "super" : "") << "class '"
                  << inserted.first->second->owner->name << "'\n"
                  << sp.location << "  ... and in superclass '" << s->name
                  << "'\n";
        return false;
      }
    }
  }

  return true;
}

std::unique_ptr<ObjectTypeVector> LoadObjectTypes(const std::string &filename) {
  std::unique_ptr<ObjectTypeVector> result(new ObjectTypeVector());

  if (!ParseObjectTypesFromFile(filename, result.get())) return nullptr;
  if (!ValidateTypes(result.get())) return nullptr;
  return result;
}

void GenerateCode(const std::string &filename,
                  const std::string &nlohmann_json_include,
                  const std::string &gen_namespace,
                  const ObjectTypeVector &objects, FILE *out) {
  fprintf(out, "// Don't modify. Generated from %s\n", filename.c_str());
  fprintf(out,
          "#pragma once\n"
          "#include <string>\n"
          "#include <vector>\n");
  fprintf(out, "#include %s\n\n", nlohmann_json_include.c_str());

  if (!gen_namespace.empty()) {
    fprintf(out, "namespace %s {\n", gen_namespace.c_str());
  }
  for (const auto &obj : objects) {
    fprintf(out, "struct %s", obj->name.c_str());
    bool is_first = true;
    for (const auto &e : obj->extends) {
      fprintf(out, "%s", is_first ? " :" : ",");
      fprintf(out, " public %s", e.c_str());
      is_first = false;
    }
    fprintf(out, " {\n");
    for (const auto &p : obj->properties) {
      std::string type;
      if (p.object_type)
        type = p.object_type->name;
      else if (p.type == "string")
        type = "std::string";
      else if (p.type == "integer")
        type = "int";
      else if (p.type == "object")
        type = "nlohmann::json";
      else if (p.type == "boolean")
        type = "bool";
      // TODO: optional and array
      if (type.empty()) {
        std::cerr << p.location << "Not supported yet '" << p.type << "'\n";
        continue;
      }
      if (p.is_array) {
        fprintf(out, "  std::vector<%s> %s", type.c_str(), p.name.c_str());
      } else {
        fprintf(out, "  %s %s", type.c_str(), p.name.c_str());
      }
      if (!p.default_value.empty())
        fprintf(out, " = %s", p.default_value.c_str());
      fprintf(out, ";\n");
      if (p.is_optional) {
        fprintf(out, "  bool has_%s = false;  // optional property\n",
                p.name.c_str());
      }
    }

    // nlohmann::json serialization
    fprintf(out, "\n");
    fprintf(out, "  void Deserialize(const nlohmann::json &j) {\n");
    for (const auto &e : obj->extends) {
      fprintf(out, "    %s::Deserialize(j);\n", e.c_str());
    }
    for (const auto &p : obj->properties) {
      int indent = 4;
      std::string access_call = "j.at(\"" + p.name + "\")";
      std::string access_deref = access_call + ".";
      if (p.is_optional) {
        fprintf(out,
                "%*sif (auto found = j.find(\"%s\"); found != j.end()) {\n",
                indent, "", p.name.c_str());
        indent += 4;
        fprintf(out, "%*shas_%s = true;\n", indent, "", p.name.c_str());
        access_call = "*found";
        access_deref = "found->";
      }
      if (p.object_type == nullptr || p.is_array) {
        fprintf(out, "%*s%sget_to(%s);\n", indent, "", access_deref.c_str(),
                p.name.c_str());
      } else {
        fprintf(out, "%*s%s.Deserialize(%s);\n", indent, "", p.name.c_str(),
                access_call.c_str());
      }
      if (p.is_optional) {
        fprintf(out, "%*s}\n", indent - 4, "");
      }
    }
    fprintf(out, "  }\n");

    fprintf(out, "  void Serialize(nlohmann::json *j) const {\n");
    for (const auto &e : obj->extends) {
      fprintf(out, "    %s::Serialize(j);\n", e.c_str());
    }
    for (const auto &p : obj->properties) {
      int indent = 4;
      if (p.is_optional) {
        fprintf(out, "%*sif (has_%s)", indent, "", p.name.c_str());
        indent = 1;
      }
      if (p.object_type == nullptr || p.is_array) {
        fprintf(out, "%*s(*j)[\"%s\"] = %s;\n", indent, "", p.name.c_str(),
                p.name.c_str());
      } else {
        fprintf(out, "%*s%s.Serialize(&(*j)[\"%s\"]);\n", indent, "",
                p.name.c_str(), p.name.c_str());
      }
    }
    fprintf(out, "  }\n");

    fprintf(out, "};\n");  // End of struct

    // functions that are picked up by the nlohmann::json serializer
    // We could generate template code once for all to_json/from_json that take
    // a T obj, but to limit method lookup confusion for other objects that
    // might interact with the json library, let's be explicit for each struct
    fprintf(out,
            "inline void to_json(nlohmann::json &j, const %s &obj) "
            "{ obj.Serialize(&j); }\n",
            obj->name.c_str());
    fprintf(out,
            "inline void from_json(const nlohmann::json &j, %s &obj) "
            "{ obj.Deserialize(j); }\n\n",
            obj->name.c_str());
  }

  if (!gen_namespace.empty()) {
    fprintf(out, "}  // %s\n", gen_namespace.c_str());
  }
}

int main(int argc, char *argv[]) {
  const auto usage =
      absl::StrCat("usage: ", argv[0], " [options] <protocol-spec-yaml>");
  const auto file_args = verible::InitCommandLine(usage, &argc, &argv);

  if (file_args.size() < 2) {
    std::cerr << "Need filename";
    return 1;
  }
  const std::string schema_filename{file_args[1].begin(), file_args[1].end()};
  auto objects = LoadObjectTypes(schema_filename);
  if (!objects) {
    fprintf(stderr, "Couldn't parse spec\n");
    return 2;
  }

  FILE *out = stdout;
  const std::string &output = absl::GetFlag(FLAGS_output);
  if (!output.empty()) {
    out = fopen(output.c_str(), "w");
    if (!out) {
      perror("opening output file");
      return 3;
    }
  }

  GenerateCode(schema_filename, absl::GetFlag(FLAGS_json_header),
               absl::GetFlag(FLAGS_class_namespace), *objects, out);
}
