// Copyright 2017-2020 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.

#ifndef VERIBLE_VERILOG_TOOLS_KYTHE_INDEXING_FACTS_TREE_H_
#define VERIBLE_VERILOG_TOOLS_KYTHE_INDEXING_FACTS_TREE_H_

#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "common/text/token_info.h"
#include "common/util/vector_tree.h"
#include "verilog/tools/kythe/verilog_extractor_indexing_fact_type.h"

namespace verilog {
namespace kythe {

// Position of the Anchor in the original text. Required to be able to reference
// Anchor's content in the original string (as Anchor is owning its content --
// string_view is not applicable).
struct AnchorRange {
  const size_t begin;
  const size_t length;

  AnchorRange(size_t b, size_t l) : begin(b), length(l) {}
};

// Anchor class represents the location and value of some token.
class Anchor {
 public:
  explicit Anchor(absl::string_view value) : content_(value) {}

  explicit Anchor(absl::string_view value, size_t begin, size_t length)
      : content_(value) {
    source_text_range_.emplace(begin, length);
  }

  // Delegates construction to use only the string_view spanned by a TokenInfo.
  // Recall the TokenInfo's string point to substrings of memory owned
  // elsewhere.
  explicit Anchor(const verible::TokenInfo& token,
                  absl::string_view source_content)
      : content_(token.text()) {
    const int token_left = token.left(source_content);
    const int token_right = token.right(source_content);
    source_text_range_.emplace(token_left, token_right - token_left);
  }

  Anchor(const Anchor&);  // TODO(fangism): delete, move-only
  Anchor(Anchor&&) = default;
  Anchor& operator=(const Anchor&) = delete;
  Anchor& operator=(Anchor&&) = delete;

  // Returns human readable view of this Anchor.
  std::string DebugString() const;

  absl::string_view Text() const { return content_; }

  // Returns the location of the Anchor's content in the original string.
  const std::optional<AnchorRange>& SourceTextRange() const {
    return source_text_range_;
  }

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

 private:
  // Substring of the original text that corresponds to this Anchor.
  std::string content_;

  std::optional<AnchorRange> source_text_range_;
};

std::ostream& operator<<(std::ostream&, const Anchor&);

// This class is a simplified representation of CST and contains information
// that can be used for extracting indexing-facts for different indexing tools.
//
// This is intended to be an abstract layer between the parser generated CST
// and the indexing tool.
class IndexingNodeData {
 public:
  template <typename... Args>
  /* implicit */ IndexingNodeData(IndexingFactType language_feature,  // NOLINT
                                  Args&&... args)
      : indexing_fact_type_(language_feature) {
    AppendAnchor(std::forward<Args>(args)...);
  }

  IndexingNodeData(const IndexingNodeData&) = default;
  IndexingNodeData& operator=(IndexingNodeData&&) = default;

  // TODO(fangism): delete copy-ctor to make this move-only
  IndexingNodeData(IndexingNodeData&&) = default;
  IndexingNodeData& operator=(const IndexingNodeData&) = delete;

  // Consume an Anchor object(s), variadically.
  template <typename... Args>
  void AppendAnchor(Anchor&& anchor, Args&&... args) {
    anchors_.emplace_back(std::move(anchor));
    AppendAnchor(std::forward<Args>(args)...);
  }

  // Swaps the anchors with the given IndexingNodeData.
  void SwapAnchors(IndexingNodeData* other) { anchors_.swap(other->anchors_); }

  // Returns human readable view of this node.
  std::ostream& DebugString(std::ostream* stream) const;

  const std::vector<Anchor>& Anchors() const { return anchors_; }
  IndexingFactType GetIndexingFactType() const { return indexing_fact_type_; }

  // Redirects all non-owned string_views to point into a different copy of the
  // same text, located 'delta' away.  This is useful for testing, when source
  // text is copied to a different location.
  void RebaseStringViewsForTesting(std::ptrdiff_t delta);

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

 private:
  // Base case for variadic AppendAnchor()
  void AppendAnchor() const {}

 private:
  // Represents which language feature this indexing fact is about.
  IndexingFactType indexing_fact_type_;

  // Anchors representing the different tokens of this indexing fact.
  std::vector<Anchor> anchors_;
};

// Without a base string_view, this displays the base-address and length of each
// Anchor's string_view.  See PrintableIndexingNodeData for a more readable
// alternative using byte-offsets.
std::ostream& operator<<(std::ostream&, const IndexingNodeData&);

// Pairs together IndexingNodeData and string_view to be a printable object.
struct PrintableIndexingNodeData {
  const IndexingNodeData& data;
  // The superstring of which all string_views in this subtree is a substring.
  const absl::string_view base;

  PrintableIndexingNodeData(const IndexingNodeData& data,
                            absl::string_view base)
      : data(data), base(base) {}
};

// Human-readable form for debugging, showing in-file byte offsets of
// string_views.
std::ostream& operator<<(std::ostream&, const PrintableIndexingNodeData&);

// Renaming for VectorTree; IndexingFactNode is actually a VectorTree which is a
// class for constructing trees and dealing with them in a elegant manner.
using IndexingFactNode = verible::VectorTree<IndexingNodeData>;

struct PrintableIndexingFactNode {
  const IndexingFactNode& data;
  // The superstring of which all string_views in this subtree is a substring.
  const absl::string_view base;

  PrintableIndexingFactNode(const IndexingFactNode& data,
                            absl::string_view base)
      : data(data), base(base) {}
};

// Human-readable form for debugging.
std::ostream& operator<<(std::ostream&, const PrintableIndexingFactNode&);

}  // namespace kythe
}  // namespace verilog

#endif  // VERIBLE_VERILOG_TOOLS_KYTHE_INDEXING_FACTS_TREE_H_
