// Copyright 2019 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.

#ifndef ZIRCON_TOOLS_KAZOO_SYSCALL_LIBRARY_H_
#define ZIRCON_TOOLS_KAZOO_SYSCALL_LIBRARY_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <set>
#include <string>
#include <variant>
#include <vector>

#include "rapidjson/document.h"
#include "tools/kazoo/macros.h"

class Alias;
class Enum;
class Struct;
class SyscallLibrary;

class TypeBool {};
class TypeChar {};
class TypeInt32 {};
class TypeInt64 {};
class TypeSizeT {};
class TypeUint16 {};
class TypeUint32 {};
class TypeUint64 {};
class TypeUint8 {};
class TypeUintptrT {};
class TypeVoid {};
class TypeZxBasicAlias;

class TypeAlias;
class TypeEnum;
class TypeHandle;
class TypePointer;
class TypeString {};
class TypeStruct;
class TypeVector;
using TypeData =
    std::variant<std::monostate, TypeBool, TypeChar, TypeInt32, TypeInt64, TypeSizeT, TypeUint16,
                 TypeUint32, TypeUint64, TypeUint8, TypeUintptrT, TypeVoid, TypeZxBasicAlias,
                 TypeAlias, TypeEnum, TypeHandle, TypePointer, TypeString, TypeStruct, TypeVector>;

class Type;

class TypeEnum {
 public:
  explicit TypeEnum(const Enum* enum_data) : enum_(enum_data) {}

  const Enum& enum_data() const { return *enum_; }

 private:
  const Enum* enum_;
};

class TypeHandle {
 public:
  explicit TypeHandle(const std::string& handle_type) : handle_type_(handle_type) {}

  const std::string& handle_type() const { return handle_type_; }

 private:
  std::string handle_type_;
};

class IsDecayedVectorTag {};

class TypePointer {
 public:
  explicit TypePointer(const Type& pointed_to_type)
      : pointed_to_type_(std::make_shared<Type>(pointed_to_type)) {}

  TypePointer(const Type& pointed_to_type, IsDecayedVectorTag)
      : pointed_to_type_(std::make_shared<Type>(pointed_to_type)), was_vector_(true) {}

  const Type& pointed_to_type() const;
  bool was_vector() const { return was_vector_; }

 private:
  std::shared_ptr<Type> pointed_to_type_;

  // This is set to true when the pointer was converted from a vector to a
  // pointer when changing from FIDL type to the target language's type. This
  // indicates that the pointer points the base of an array of
  // pointed-to-types, rather than just pointing at a single one.
  bool was_vector_{false};
};

class TypeAlias {
 public:
  explicit TypeAlias(const Alias* alias_data) : alias_(alias_data) {}

  const Alias& alias_data() const { return *alias_; }

 private:
  const Alias* alias_;
};

class TypeStruct {
 public:
  explicit TypeStruct(const Struct* struct_data) : struct_(struct_data) {}

  const Struct& struct_data() const { return *struct_; }

 private:
  const Struct* struct_;
};

class UseUint32ForVectorSizeTag {};

class TypeVector {
 public:
  explicit TypeVector(const Type& contained_type)
      : contained_type_(std::make_shared<Type>(contained_type)) {}

  explicit TypeVector(const Type& contained_type, UseUint32ForVectorSizeTag)
      : contained_type_(std::make_shared<Type>(contained_type)), uint32_size_(true) {}

  const Type& contained_type() const;
  bool uint32_size() const { return uint32_size_; }

 private:
  std::shared_ptr<Type> contained_type_;
  bool uint32_size_{false};
};

// A FIDL type alias pointing to one of the zircon "builtins". e.g. Futex, koid.
// We want to implement special treatment for these types.
class TypeZxBasicAlias {
 public:
  explicit TypeZxBasicAlias(const std::string& name)
      : name_("zx_" + name + "_t"),
        go_name_(std::string(1, static_cast<char>(toupper(name[0]))) + name.substr(1)) {}

  const std::string& name() const { return name_; }
  const std::string& go_name() const { return go_name_; }

 private:
  std::string name_;
  std::string go_name_;
};

inline const Type& TypeVector::contained_type() const { return *contained_type_; }
inline const Type& TypePointer::pointed_to_type() const { return *pointed_to_type_; }

enum class Constness {
  kUnspecified,
  kConst,
  kMutable,
};

enum class Optionality {
  kUnspecified,
  kInputArgument,
  kOutputNonOptional,
  kOutputOptional,
};

class Type {
 public:
  Type() = default;
  explicit Type(TypeData type_data) : type_data_(std::move(type_data)) {}
  Type(TypeData type_data, Constness constness)
      : type_data_(std::move(type_data)), constness_(constness) {}
  Type(TypeData type_data, Constness constness, Optionality optionality)
      : type_data_(std::move(type_data)), constness_(constness), optionality_(optionality) {}
  ~Type() = default;

  const TypeData& type_data() const { return type_data_; }
  void set_type_data(const TypeData& type_data) { type_data_ = type_data; }

  Optionality optionality() const { return optionality_; }
  void set_optionality(Optionality optionality) { optionality_ = optionality; }

  Constness constness() const { return constness_; }
  void set_constness(Constness constness) { constness_ = constness; }

  bool IsChar() const { return std::holds_alternative<TypeChar>(type_data_); }
  bool IsVoid() const { return std::holds_alternative<TypeVoid>(type_data_); }
  bool IsVector() const { return std::holds_alternative<TypeVector>(type_data_); }
  bool IsPointer() const { return std::holds_alternative<TypePointer>(type_data_); }
  bool IsString() const { return std::holds_alternative<TypeString>(type_data_); }
  bool IsStruct() const { return std::holds_alternative<TypeStruct>(type_data_); }
  bool IsHandle() const { return std::holds_alternative<TypeHandle>(type_data_); }
  bool IsSignedInt() const {
    return std::holds_alternative<TypeChar>(type_data_) ||
           std::holds_alternative<TypeInt32>(type_data_) ||
           std::holds_alternative<TypeInt64>(type_data_);
  }
  bool IsUnsignedInt() const {
    return std::holds_alternative<TypeUint8>(type_data_) ||
           std::holds_alternative<TypeUint16>(type_data_) ||
           std::holds_alternative<TypeUint32>(type_data_) ||
           std::holds_alternative<TypeUint64>(type_data_);
  }

  const TypeVector& DataAsVector() const { return std::get<TypeVector>(type_data_); }
  const TypePointer& DataAsPointer() const { return std::get<TypePointer>(type_data_); }
  const TypeStruct& DataAsStruct() const { return std::get<TypeStruct>(type_data_); }

  bool IsSimpleType() const { return !IsVector() && !IsString() && !IsStruct(); }

 private:
  TypeData type_data_;
  Constness constness_{Constness::kUnspecified};
  Optionality optionality_{Optionality::kUnspecified};
};

class Alias {
 public:
  Alias() = default;
  ~Alias() = default;

  const std::string& id() const { return id_; }
  const std::string& original_name() const { return original_name_; }
  const std::string& base_name() const { return base_name_; }
  const std::string& partial_type_ctor() const { return partial_type_ctor_; }
  const std::vector<std::string>& description() const { return description_; }

 private:
  friend class SyscallLibraryLoader;

  std::string id_;                 // "zx/MyAlias"
  std::string original_name_;      // "MyAlias"
  std::string base_name_;          // "my_alias"
  std::string partial_type_ctor_;  // "uint64"
  std::vector<std::string> description_;

  DISALLOW_COPY_AND_ASSIGN(Alias);
};

class StructMember {
 public:
  StructMember() = default;
  StructMember(const std::string& name, const Type& type,
               const std::map<std::string, std::string>& attributes)
      : name_(name), type_(type), attributes_(attributes) {}
  ~StructMember() = default;

  const std::string& name() const { return name_; }

  const Type& type() const { return type_; }
  void set_type(const Type& type) { type_ = type; }

  const std::map<std::string, std::string>& attributes() const { return attributes_; }

 private:
  friend class SyscallLibraryLoader;

  std::string name_;
  Type type_;
  std::map<std::string, std::string> attributes_;
};

class Struct {
 public:
  Struct() = default;
  ~Struct() = default;

  const std::string& id() const { return id_; }
  const std::string& original_name() const { return original_name_; }
  const std::string& base_name() const { return base_name_; }
  const std::vector<StructMember>& members() const { return members_; }

 private:
  friend class SyscallLibraryLoader;

  std::string id_;             // "zx/HandleInfo"
  std::string original_name_;  // "HandleInfo"
  std::string base_name_;      // "handle_info"
  std::vector<StructMember> members_;

  DISALLOW_COPY_AND_ASSIGN(Struct);
};

class Syscall {
 public:
  Syscall() = default;
  ~Syscall() = default;

  const std::string& short_description() const { return short_description_; }
  const std::map<std::string, std::string>& attributes() const { return attributes_; }

  const std::string& id() const { return id_; }
  const std::string& original_name() const { return original_name_; }
  const std::string& category() const { return category_; }
  const std::string& name() const { return name_; }
  bool is_noreturn() const { return is_noreturn_; }
  const Struct& request() const { return request_; }
  const Struct& response() const { return response_; }
  const std::vector<std::string>& rights_specs() const { return rights_specs_; }

  bool HasAttribute(const char* attrib_name) const;
  std::string GetAttribute(const char* attrib_name) const;

  const Type& kernel_return_type() const { return kernel_return_type_; }
  const std::vector<StructMember>& kernel_arguments() const { return kernel_arguments_; }
  size_t num_kernel_args() const { return kernel_arguments_.size(); }

 private:
  friend class SyscallLibraryLoader;
  bool MapRequestResponseToKernelAbi();
  bool HandleArgReorder();

  std::string id_;             // "zx/Object"
  std::string original_name_;  // "GetInfo"
  std::string category_;       // "object"
  std::string name_;           // "object_get_info"
  std::string short_description_;
  bool is_noreturn_ = false;
  std::map<std::string, std::string> attributes_;
  Struct request_;
  Struct response_;
  std::vector<std::string> rights_specs_;

  // request_ and response_ mapped to C/Kernel-style call style.
  Type kernel_return_type_;
  std::vector<StructMember> kernel_arguments_;

  DISALLOW_COPY_AND_ASSIGN(Syscall);
};

enum class Required { kNo, kYes };

class TableMember {
 public:
  TableMember() = default;
  TableMember(const std::string& name, const Type& type,
              const std::vector<std::string>& description, Required required)
      : name_(name), type_(type), description_(description), required_(required) {}
  ~TableMember() = default;

  const std::string& name() const { return name_; }
  const Type& type() const { return type_; }
  const std::vector<std::string>& description() const { return description_; }
  Required required() const { return required_; }

 private:
  friend class SyscallLibraryLoader;

  std::string name_;
  Type type_;
  std::vector<std::string> description_;
  Required required_;
};

class Table {
 public:
  Table() = default;
  ~Table() = default;

  const std::string& id() const { return id_; }
  const std::string& original_name() const { return original_name_; }
  const std::string& base_name() const { return base_name_; }
  const std::vector<std::string>& description() const { return description_; }
  const std::vector<TableMember>& members() const { return members_; }

 private:
  friend class SyscallLibraryLoader;

  std::string id_;             // "zx/HandleInfo"
  std::string original_name_;  // "HandleInfo"
  std::string base_name_;      // "handle_info"
  std::vector<std::string> description_;
  std::vector<TableMember> members_;

  DISALLOW_COPY_AND_ASSIGN(Table);
};

struct EnumMember {
  uint64_t value;
  std::vector<std::string> description;
};

class Enum {
 public:
  Enum() = default;
  ~Enum() = default;

  const std::string& id() const { return id_; }                        // "zx/ProfileInfoType"
  const std::string& original_name() const { return original_name_; }  // "ProfileInfoType"
  const std::string& base_name() const { return base_name_; }          // "profile_info_type"
  const std::vector<std::string>& description() const { return description_; }

  void AddMember(const std::string& member_name, EnumMember member);
  bool HasMember(const std::string& member_name) const;
  const EnumMember& ValueForMember(const std::string& member_name) const;

  const std::vector<std::string>& members() const { return insertion_order_; }
  const Type& underlying_type() const { return underlying_type_; }

 private:
  friend class SyscallLibraryLoader;

  std::string id_;
  std::string original_name_;
  std::string base_name_;
  std::vector<std::string> description_;
  Type underlying_type_;                       // uint32_t etc.
  std::map<std::string, EnumMember> members_;  // Maps enumeration name to value (kWhatever = 12).
  std::vector<std::string> insertion_order_;
};

class SyscallLibrary {
 public:
  SyscallLibrary() = default;
  ~SyscallLibrary() = default;

  const std::string& name() const { return name_; }  // "zx"
  const std::vector<std::unique_ptr<Enum>>& bits() const { return bits_; }
  const std::vector<std::unique_ptr<Enum>>& enums() const { return enums_; }
  const std::vector<std::unique_ptr<Syscall>>& syscalls() const { return syscalls_; }
  const std::vector<std::unique_ptr<Alias>>& type_aliases() const { return type_aliases_; }
  const std::vector<std::unique_ptr<Table>>& tables() const { return tables_; }

  Type TypeFromIdentifier(const std::string& id) const;
  Type TypeFromName(const std::string& name) const;

  void FilterSyscalls(const std::set<std::string>& attributes_to_exclude);

 private:
  friend class SyscallLibraryLoader;

  std::string name_;
  std::vector<std::unique_ptr<Enum>> bits_;
  std::vector<std::unique_ptr<Enum>> enums_;
  std::vector<std::unique_ptr<Struct>> structs_;
  std::vector<std::unique_ptr<Syscall>> syscalls_;
  std::vector<std::unique_ptr<Alias>> type_aliases_;
  std::vector<std::unique_ptr<Table>> tables_;

  DISALLOW_COPY_AND_ASSIGN(SyscallLibrary);
};

class SyscallLibraryLoader {
 public:
  // Loads a JSON representation of syscalls into a SyscallLibrary structure.
  // Returns true on success, or false with a message logged.
  static bool FromJson(const std::string& json_ir, SyscallLibrary* library);

 private:
  static bool LoadBits(const rapidjson::Document& document, SyscallLibrary* library);
  static bool LoadEnums(const rapidjson::Document& document, SyscallLibrary* library);
  static bool LoadInterfaces(const rapidjson::Document& document, SyscallLibrary* library);
  static bool LoadTypeAliases(const rapidjson::Document& document, SyscallLibrary* library);
  static bool LoadStructs(const rapidjson::Document& document, SyscallLibrary* library);
  static bool LoadTables(const rapidjson::Document& document, SyscallLibrary* library);

  static std::unique_ptr<Enum> ConvertBitsOrEnumMember(const rapidjson::Value& json);
};

#endif  // ZIRCON_TOOLS_KAZOO_SYSCALL_LIBRARY_H_
