// Copyright 2017-2022 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_FLOW_TREE_H_
#define VERIBLE_VERILOG_FLOW_TREE_H_

#include <bitset>
#include <map>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "common/text/token_stream_view.h"

namespace verilog {

// FlowTree class builds the control flow graph of a tokenized System-Verilog
// source code. Furthermore, enabling doing the following queries on the graph:
// - Generating all the possible variants (provided via a callback function).
class FlowTree {
 private:
  // 'kMaxDistinctMacros' shows the maximum number of distinct macros that can
  // be considered in conditonal directives.
  static constexpr int kMaxDistinctMacros = 128;

 public:
  using BitSet = std::bitset<kMaxDistinctMacros>;
  using TokenSequenceConstIterator = verible::TokenSequence::const_iterator;

  // "ConditionalBlock" saves locations of conditionals in a "TokenSequence".
  //  All locations should point inside this specific "TokenSequence".
  //  Since it is only used in conjunction with a "TokenSequence",
  //  It should be initialized to last location in this "TokenSequence",
  //  For example in "GenerateControlFlowTree" is initialized to
  //  'source_sequence_.end()'.

  struct Variant {
    // Contains the token sequence of the variant.
    verible::TokenSequence sequence;

    // The i-th bit in "macros_mask" is 1 when the macro (with ID = i) is
    // assumed to be defined, otherwise it is assumed to be undefined.
    BitSet macros_mask;

    // The i-th bit in "visited" is 1 when the macro (with ID = i) is visited or
    // assumed (either defined or not), otherwise it is not visited (its value
    // doesn't affect this variant).
    //
    // e.g.:
    //  `ifdef A
    //    `ifdef B
    //    ...
    //    `endif
    //  `endif
    //
    // Consider the variant in which A is undefined,
    // we notice that B doesn't affect the variant.
    // Then the bit corresponding to B in "visited" is 0.
    BitSet visited;
  };

  // Receive a complete token sequence of one variant.
  // variant_sequence: the generated variant token sequence.
  using VariantReceiver = std::function<bool(const Variant &variant)>;

  explicit FlowTree(verible::TokenSequence source_sequence)
      : source_sequence_(std::move(source_sequence)){};

  // Generates all possible variants.
  absl::Status GenerateVariants(const VariantReceiver &receiver);

  // Returns all the used macros in conditionals, ordered with the same ID as
  // used in BitSets.
  const std::vector<TokenSequenceConstIterator> &GetUsedMacros() {
    return conditional_macros_;
  }

 private:
  struct ConditionalBlock {
    ConditionalBlock(TokenSequenceConstIterator if_location,
                     TokenSequenceConstIterator non_location)
        : if_location(if_location),
          else_location(non_location),
          endif_location(non_location) {}

    // "if_location" points to `ifdef or `ifndef.
    TokenSequenceConstIterator if_location;
    std::vector<TokenSequenceConstIterator> elsif_locations;
    TokenSequenceConstIterator else_location;
    TokenSequenceConstIterator endif_location;
  };

  // Constructs the control flow tree by adding the tree edges in edges_.
  absl::Status GenerateControlFlowTree();

  // Traveses the tree in a depth first manner.
  absl::Status DepthFirstSearch(const VariantReceiver &receiver,
                                TokenSequenceConstIterator current_node);

  // Checks if the iterator points to a conditonal directive (`ifdef/ifndef...).
  static bool IsConditional(TokenSequenceConstIterator iterator);

  // Adds all edges withing a conditional block.
  absl::Status AddBlockEdges(const ConditionalBlock &block);

  // The tree edges which defines the possible next childs of each token in
  // source_sequence_.
  std::map<TokenSequenceConstIterator, std::vector<TokenSequenceConstIterator>>
      edges_;

  // Extracts the conditional macro checked.
  static absl::Status MacroFollows(
      TokenSequenceConstIterator conditional_iterator);

  // Adds macro to conditional_macros_ vector, and save its ID in
  // conditional_macro_id_ map.
  absl::Status AddMacroOfConditional(
      TokenSequenceConstIterator conditional_iterator);

  int GetMacroIDOfConditional(TokenSequenceConstIterator conditional_iterator);

  // Holds all of the conditional blocks.
  std::vector<ConditionalBlock> if_blocks_;

  // The original source code lexed token seqouence.
  const verible::TokenSequence source_sequence_;

  // Current variant being generated by DepthFirstSearch.
  Variant current_variant_;

  // A flag that determines if the VariantReceiver returned 'false'.
  // By default: it assumes VariantReceiver wants more variants.
  bool wants_more_ = 1;

  // Mapping each conditional macro to an integer ID,
  // to use it later as a bit offset.
  std::map<absl::string_view, int> conditional_macro_id_;

  // A vector containing all the macros used placed by their given ID.
  std::vector<TokenSequenceConstIterator> conditional_macros_;

  // Number of macros appeared in `ifdef/`ifndef/`elsif.
  int conditional_macros_counter_ = 0;
};

}  // namespace verilog

#endif  // VERIBLE_VERILOG_FLOW_TREE_H_
