// 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 SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_INDEX_NODE_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_INDEX_NODE_H_

#include <iosfwd>
#include <map>
#include <string>
#include <vector>

namespace zxdb {

class DwarfSymbolFactory;

// An in-progress replacement for IndexNode. Not ready to use yet.
class IndexNode {
 public:
  using Map = std::map<std::string, IndexNode>;

  // The type of an index node. There are several "physical" kinds which are associated with
  // children of each node. These physical ones count up from 0 so one can iterate over them
  // from to up until < kEndPhysical to iterate the child categories.
  enum class Kind : int {
    kNamespace = 0,
    kType,
    kFunction,
    kVar,
    kEndPhysical,  // Marker for the end of the kinds that have children for every node.

    kNone = kEndPhysical,
    kRoot,  // Root index node (meaning nothing semantically).
  };

  // A reference to a DIE that doesn't need the unit or the underlying llvm::DwarfDebugInfoEntry to
  // be kept. This allows the discarding of the full parsed DIE structures after indexing. It can be
  // converted back to a DIE, which will cause the DWARFUnit to be re-parsed.
  //
  // The offset stored in this structure is the offset from the beginning of the .debug_info
  // section, which is the same as the offset stored in the llvm::DWARFDebugInfoEntry.
  //
  // Random code reading the index can convert a SymbolRef to a Symbol object using
  // ModuleSymbols::IndexSymbolRefToSymbol().
  //
  // TODO(bug 53091) in the future we may want to add ELF symbol support to this class.
  class SymbolRef {
   public:
    enum Kind {
      kNull,              // Empty.
      kDwarf,             // Normal DWARF symbol.
      kDwarfDeclaration,  // A DWARF declaration.
    };

    SymbolRef() = default;
    SymbolRef(Kind kind, uint32_t offset) : kind_(kind), offset_(offset) {}

    Kind kind() const { return kind_; }
    bool is_declaration() const { return kind_ == kDwarfDeclaration; }
    uint32_t offset() const { return offset_; }

   private:
    Kind kind_ = kNull;
    uint32_t offset_ = 0;
  };

  explicit IndexNode(Kind kind) : kind_(kind) {}
  ~IndexNode() = default;

  Kind kind() const { return kind_; }

  // The SymbolRef can be omitted when indexing namespaces as the DIEs are not stored for that case.
  IndexNode* AddChild(Kind kind, const char* name);
  IndexNode* AddChild(Kind kind, const char* name, const SymbolRef& ref);
  void AddDie(const SymbolRef& ref);

  const Map& namespaces() const { return children_[static_cast<int>(Kind::kNamespace)]; }
  Map& namespaces() { return children_[static_cast<int>(Kind::kNamespace)]; }

  const Map& types() const { return children_[static_cast<int>(Kind::kType)]; }
  Map& types() { return children_[static_cast<int>(Kind::kType)]; }

  const Map& functions() const { return children_[static_cast<int>(Kind::kFunction)]; }
  Map& functions() { return children_[static_cast<int>(Kind::kFunction)]; }

  const Map& vars() const { return children_[static_cast<int>(Kind::kVar)]; }
  Map& vars() { return children_[static_cast<int>(Kind::kVar)]; }

  // Returns the map for the given child kind. This will assert for >= kEndPhysical ("kNone" and
  // "kRoot") which aren't child kinds.
  const Map& MapForKind(Kind kind) const;
  Map& MapForKind(Kind kind);

  // AsString is useful only in small unit tests since even a small module can have many megabytes
  // of dump.
  std::string AsString(int indent_level = 0) const;

  // Dump DIEs for debugging. A node does not contain its own name (this is stored in the parent's
  // map). If printing some node other than the root, specify the name.
  //
  // If non-null, |factory_for_loc| will be used to add extra location information to certain types
  // of entries. Currently this prints out the relative code ranges for functions, and the DIE
  // offset of the indexed item for everything else.
  void Dump(std::ostream& out, DwarfSymbolFactory* factory_for_loc = nullptr,
            int indent_level = 0) const;
  void Dump(const std::string& name, std::ostream& out,
            DwarfSymbolFactory* factory_for_loc = nullptr, int indent_level = 0) const;

  const std::vector<SymbolRef>& dies() const { return dies_; }

 private:
  Kind kind_;

  // TODO(brettw) evaluate whether we can save a lot of memory using optionally-null unique_ptrs
  // here since in most cases all but one of these maps will be empty.
  Map children_[static_cast<int>(Kind::kEndPhysical)];

  // Contains the references to the definitions (if possible) or the declarations (if not) of the
  // type, function, or variable. This will not have any entries for namespaces.
  //
  // TODO(brettw) consider an optimization because in most cases there will be exactly one DIE.
  std::vector<SymbolRef> dies_;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_INDEX_NODE_H_
