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

#include "verilog/analysis/verilog_excerpt_parse.h"

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

#include "absl/status/status.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "common/text/text_structure.h"
#include "common/util/container_util.h"
#include "common/util/logging.h"
#include "verilog/analysis/verilog_analyzer.h"

// TODO(hzeller): All these are constructing strings with prefix and postfix.
// And often, these constructs are used in fallback situations in which we
// couldn't parse something and try again in a different setting. That means
// it generates a new string copy and forces full lexing again.
//
// Investigate if we can just take the original token stream and add tokens
// in front and back (should work if these tokens don't bring the lexer into
// a specific state)
// https://github.com/chipsalliance/verible/issues/1519

namespace verilog {

using verible::container::FindOrNull;

// Function template to create any mini-parser for Verilog.
// 'prolog' and 'epilog' are text that wrap around the 'text' argument to
// form a whole Verilog source.
// The returned analyzer's text structure will discard parsed information
// about the prolog and epilog, leaving only the substructure of interest.
static std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogConstruct(
    absl::string_view prolog, absl::string_view text, absl::string_view epilog,
    absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  VLOG(2) << __FUNCTION__;
  CHECK(epilog.empty() || absl::ascii_isspace(epilog[0]))
      << "epilog text must begin with a whitespace to prevent unintentional "
         "token-joining and escaped-identifier extension.";
  const std::string analyze_text = absl::StrCat(prolog, text, epilog);
  // Disable parser directive comments because a specific parser
  // is already being selected.
  auto analyzer_ptr = std::make_unique<VerilogAnalyzer>(analyze_text, filename,
                                                        preprocess_config);

  if (!ABSL_DIE_IF_NULL(analyzer_ptr)->Analyze().ok()) {
    VLOG(2) << __FUNCTION__ << ": Analyze() failed.  code:\n" << analyze_text;
    // Continue to processes, even if there's an error, so that token
    // string_views can be properly rebased.
    // There may or may not be a formed syntax tree.
  }

  // Trim off prolog and epilog from internal text structure to make it look
  // as if only text were analyzed.
  analyzer_ptr->MutableData().FocusOnSubtreeSpanningSubstring(prolog.length(),
                                                              text.length());
  // TODO(b/129905498): Strengthen check on the resulting syntax tree root,
  // by qualifying it against an expected nonterminal node type(s).
  VLOG(2) << "end of " << __FUNCTION__;
  return analyzer_ptr;  // Let caller check analyzer_ptr's status.
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogPropertySpec(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  return AnalyzeVerilogConstruct("module foo;\nproperty p;\n", text,
                                 "\nendproperty;\nendmodule;\n", filename,
                                 preprocess_config);
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogStatements(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  return AnalyzeVerilogConstruct("function foo();\n", text, "\nendfunction\n",
                                 filename, preprocess_config);
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogExpression(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  return AnalyzeVerilogConstruct("module foo;\nif (", text,
                                 " ) $error;\nendmodule\n", filename,
                                 preprocess_config);
  // $error in this context is an elaboration system task
  // The space before the ) is critical to accommodate escaped identifiers.
  // Without the space, lexing an escaped identifier would consume part
  // of the epilog text.
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogModuleBody(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  return AnalyzeVerilogConstruct("module foo;\n", text, "\nendmodule\n",
                                 filename, preprocess_config);
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogClassBody(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  return AnalyzeVerilogConstruct("class foo;\n", text, "\nendclass\n", filename,
                                 preprocess_config);
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogPackageBody(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  return AnalyzeVerilogConstruct("package foo;\n", text, "\nendpackage\n",
                                 filename, preprocess_config);
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogLibraryMap(
    absl::string_view text, absl::string_view filename,
    const VerilogPreprocess::Config &preprocess_config) {
  // The prolog/epilog strings come from verilog.lex as token enums:
  // PD_LIBRARY_SYNTAX_BEGIN and PD_LIBRARY_SYNTAX_END.
  // These are used in verilog.y to enclose the complete library_description
  // grammar rule.
  return AnalyzeVerilogConstruct(
      "`____verible_verilog_library_begin____\n", text,
      "\n`____verible_verilog_library_end____\n", filename, preprocess_config);
}

std::unique_ptr<VerilogAnalyzer> AnalyzeVerilogWithMode(
    absl::string_view text, absl::string_view filename, absl::string_view mode,
    const VerilogPreprocess::Config &preprocess_config) {
  static const auto *func_map =
      new std::map<absl::string_view,
                   std::function<std::unique_ptr<VerilogAnalyzer>(
                       absl::string_view, absl::string_view,
                       const VerilogPreprocess::Config &)>>{
          {"parse-as-statements", &AnalyzeVerilogStatements},
          {"parse-as-expression", &AnalyzeVerilogExpression},
          {"parse-as-module-body", &AnalyzeVerilogModuleBody},
          {"parse-as-class-body", &AnalyzeVerilogClassBody},
          {"parse-as-package-body", &AnalyzeVerilogPackageBody},
          {"parse-as-property-spec", &AnalyzeVerilogPropertySpec},
          {"parse-as-library-map", &AnalyzeVerilogLibraryMap},
      };
  const auto *func_ptr = FindOrNull(*func_map, mode);
  if (!func_ptr) return nullptr;
  return (*func_ptr)(text, filename, preprocess_config);
}

}  // namespace verilog
