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

// VerilogPreprocess is a *pseudo*-preprocessor for Verilog.
// Unlike a conventional preprocessor, this pseudo-preprocessor does not open
// included files, nor does it evaluate preprocessor expressions.
// Instead, it does a best-effort handling of preprocessor directives
// locally within one file, and no additional context.
// For example, it may expand a macro call if its definition happens to be
// available, but it is not required to do so.
// The pseudo-preprocessor is free to evaluate any/all/no conditional
// branches.
// Each analysis tool may configure the pseudo-preprocessor differently.

// TODO(fangism): expand macros if locally defined, and feed un-lexed
//   body text to lexer.  This approach works if the definition text
//   does not depend on the start-condition state at the macro call site.
// TODO(fangism): implement conditional evaluation policy (`ifdef, `else, ...)
// TODO(fangism): token concatenation, e.g. a``b
//   This will produce tokens that are not in the original source text.
// TODO(fangism): token string-ification (turning symbol names into strings)
// TODO(fangism): evaluate `defines inside `defines at expansion time.

#ifndef VERIBLE_VERILOG_PREPROCESSOR_VERILOG_PREPROCESS_H_
#define VERIBLE_VERILOG_PREPROCESSOR_VERILOG_PREPROCESS_H_

#include <functional>
#include <map>
#include <memory>
#include <stack>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "common/text/macro_definition.h"
#include "common/text/text_structure.h"
#include "common/text/token_info.h"
#include "common/text/token_stream_view.h"
#include "verilog/analysis/verilog_filelist.h"

namespace verilog {

// TODO(fangism): configuration policy enums.

// VerilogPreprocessError contains preprocessor error information.
// TODO(hzeller): should we just use verible::RejectedToken here ?
struct VerilogPreprocessError {
  verible::TokenInfo token_info;  // offending token
  std::string error_message;

  VerilogPreprocessError(const verible::TokenInfo& token,
                         const std::string& message)
      : token_info(token), error_message(message) {}
};

// Information that results from preprocessing.
struct VerilogPreprocessData {
  using MacroDefinition = verible::MacroDefinition;
  using MacroDefinitionRegistry = std::map<absl::string_view, MacroDefinition>;
  using TokenSequence = std::vector<verible::TokenInfo>;

  // Resulting token stream after preprocessing
  verible::TokenStreamView preprocessed_token_stream;
  std::vector<TokenSequence> lexed_macros_backup;

  // A backup memory that owns the content of the included files.
  std::vector<std::unique_ptr<verible::TextStructure>> included_text_structure;

  // Map of defined macros.
  MacroDefinitionRegistry macro_definitions;

  // Sequence of tokens rejected by preprocessing.
  // TODO(hzeller): Until we have a severity in VerilogPreprocessError, these
  // are two separate vectors.
  std::vector<VerilogPreprocessError> errors;
  std::vector<VerilogPreprocessError> warnings;
};

// VerilogPreprocess transforms a TokenStreamView.
// The input stream view is expected to have been stripped of whitespace.
class VerilogPreprocess {
  using TokenStreamView = verible::TokenStreamView;
  using MacroDefinition = verible::MacroDefinition;
  using MacroParameterInfo = verible::MacroParameterInfo;

 public:
  using FileOpener =
      std::function<absl::StatusOr<absl::string_view>(absl::string_view)>;
  struct Config {
    // Filter out non-matching `ifdef and `ifndef branches depending on
    // which defines are set.
    //
    // This option is useful for syntax check and possibly linting in
    // case parsing fails with all consecutive branches emitted.
    //
    // Note, for formatting, we do _not_ want to filter the output as we
    // want to emit all tokens.
    bool filter_branches = false;

    // Inlude files with `include.
    bool include_files = false;

    // Expand macro definition bodies, this will relexes the macro body.
    bool expand_macros = false;
    // TODO(hzeller): Provide a map of command-line provided +define+'s
  };

  explicit VerilogPreprocess(const Config& config);
  VerilogPreprocess(const Config& config, FileOpener opener);

  // Initialize preprocessing with safe default options
  // TODO(hzeller): remove this constructor once all places using the
  // preprocessor have been updated to pass a config.
  VerilogPreprocess() : VerilogPreprocess(Config()){};

  // ScanStream reads in a stream of tokens returns the result as a move
  // of preprocessor_data_.  preprocessor_data_ should not be accessed
  // after this returns.
  VerilogPreprocessData ScanStream(const TokenStreamView& token_stream);

  // TODO(fangism): ExpandMacro, ExpandMacroCall
  // TODO(b/111544845): ExpandEvalStringLiteral

  // Sets the preprocessing information containing defines and incdirs.
  void setPreprocessingInfo(
      const verilog::FileList::PreprocessingInfo& preprocess_info);

 private:
  using StreamIteratorGenerator =
      std::function<TokenStreamView::const_iterator()>;

  // Extract macro name after `define, `ifdef, `elsif ... and returns
  // iterator of macro name or a failure status.
  // Updates error messages on failure.
  absl::StatusOr<TokenStreamView::const_iterator> ExtractMacroName(
      const StreamIteratorGenerator&);

  absl::Status HandleTokenIterator(TokenStreamView::const_iterator,
                                   const StreamIteratorGenerator&);
  absl::Status HandleMacroIdentifier(TokenStreamView::const_iterator,
                                     const StreamIteratorGenerator&,
                                     bool forward);

  absl::Status HandleDefine(TokenStreamView::const_iterator,
                            const StreamIteratorGenerator&);
  absl::Status HandleUndef(TokenStreamView::const_iterator,
                           const StreamIteratorGenerator&);

  absl::Status HandleIf(TokenStreamView::const_iterator ifpos,
                        const StreamIteratorGenerator&);
  absl::Status HandleElse(TokenStreamView::const_iterator else_pos);
  absl::Status HandleEndif(TokenStreamView::const_iterator endif_pos);

  static absl::Status ConsumeAndParseMacroCall(TokenStreamView::const_iterator,
                                               const StreamIteratorGenerator&,
                                               verible::MacroCall*,
                                               const verible::MacroDefinition&);

  // The following functions return nullptr when there is no error:
  absl::Status ConsumeMacroDefinition(const StreamIteratorGenerator&,
                                      TokenStreamView*);

  static std::unique_ptr<VerilogPreprocessError> ParseMacroDefinition(
      const TokenStreamView&, MacroDefinition*);

  static std::unique_ptr<VerilogPreprocessError> ParseMacroParameter(
      TokenStreamView::const_iterator*, MacroParameterInfo*);

  void RegisterMacroDefinition(const MacroDefinition&);
  absl::Status ExpandText(const absl::string_view&);
  absl::Status ExpandMacro(const verible::MacroCall&,
                           const verible::MacroDefinition*);
  absl::Status HandleInclude(TokenStreamView::const_iterator,
                             const StreamIteratorGenerator&);

  // Generate a const_iterator to a non-whitespace token.
  static TokenStreamView::const_iterator GenerateBypassWhiteSpaces(
      const StreamIteratorGenerator&);

  const Config config_;

  // State of a block that can have a sequence of sub-blocks with conditions
  // (ifdef/elsif/else/endif). Only the first of the subblock whose condition
  // matches will be selected - or the else block if none before matched.
  class BranchBlock {
   public:
    BranchBlock(bool is_enabled, bool condition,
                const verible::TokenInfo& token)
        : outer_scope_enabled_(is_enabled), branch_token_(token) {
      UpdateCondition(token, condition);
    }

    // Is the current block selected, i.e. should tokens pass through.
    bool InSelectedBranch() const {
      return outer_scope_enabled_ && current_branch_condition_met_;
    }

    // Update condition e.g. in `elsif. Return 'false' if already in an
    // else clause.
    bool UpdateCondition(const verible::TokenInfo& token, bool condition) {
      if (in_else_) return false;
      branch_token_ = token;
      // Only the first in a row of matching conditions will select block.
      current_branch_condition_met_ = !any_branch_matched_ && condition;
      any_branch_matched_ |= condition;
      return true;
    }

    // Start an `else block. Uses its internal state to determine if
    // this will put is InSelectedBranch().
    // Returns 'false' if already in an else block.
    bool StartElse(const verible::TokenInfo& token) {
      if (in_else_) return false;
      in_else_ = true;
      branch_token_ = token;
      current_branch_condition_met_ = !any_branch_matched_;
      return true;
    }

    const verible::TokenInfo& token() const { return branch_token_; }

   private:
    const bool outer_scope_enabled_;
    verible::TokenInfo branch_token_;  // FYI for error reporting.
    bool any_branch_matched_ = false;  // only if no branch, `else will
    bool in_else_ = false;
    bool current_branch_condition_met_;
  };

  // State of nested conditional blocks. For code simplicity, this always has
  // a toplevel branch that is selected.
  std::stack<BranchBlock> conditional_block_;

  // Results of preprocessing
  VerilogPreprocessData preprocess_data_;

  // Defines and incdirs Information passed externally.
  FileList::PreprocessingInfo preprocess_info_;

  // A pointer to a file opener function.
  // This is needed for opening new files while handling includes.
  const FileOpener file_opener_ = nullptr;
};

}  // namespace verilog

#endif  // VERIBLE_VERILOG_PREPROCESSOR_VERILOG_PREPROCESS_H_
