// 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/CST/declaration.h"

#include <map>
#include <memory>
#include <utility>

#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/constants.h"
#include "common/text/symbol.h"
#include "common/text/token_info.h"
#include "common/text/tree_utils.h"
#include "common/util/container_util.h"
#include "verilog/CST/identifier.h"
#include "verilog/CST/verilog_matchers.h"
#include "verilog/CST/verilog_nonterminals.h"
#include "verilog/parser/verilog_token_enum.h"

namespace verilog {
using verible::Symbol;
using verible::SymbolPtr;
using verible::SyntaxTreeNode;
using verible::container::FindWithDefault;

SymbolPtr RepackReturnTypeId(SymbolPtr type_id_tuple) {
  auto& node = CheckSymbolAsNode(*type_id_tuple,
                                 NodeEnum::kDataTypeImplicitBasicIdDimensions);
  return verible::MakeNode(std::move(node[0]) /* type */,
                           std::move(node[1]) /* id */);
  // Discard unpacked dimensions node[2], should be nullptr, and not
  // syntactically valid.
}

NodeEnum DeclarationKeywordToNodeEnum(const Symbol& symbol) {
  static const auto* node_map = new std::map<verilog_tokentype, NodeEnum>{
      {TK_module, NodeEnum::kModuleDeclaration},
      {TK_macromodule, NodeEnum::kMacroModuleDeclaration},
      {TK_program, NodeEnum::kProgramDeclaration},
      {TK_interface, NodeEnum::kInterfaceDeclaration},
  };
  return FindWithDefault(
      *node_map,
      verilog_tokentype(verible::SymbolCastToLeaf(symbol).get().token_enum()),
      NodeEnum(verible::kUntagged));
}

std::vector<verible::TreeSearchMatch> FindAllDataDeclarations(
    const Symbol& root) {
  return SearchSyntaxTree(root, NodekDataDeclaration());
}

std::vector<verible::TreeSearchMatch> FindAllNetVariables(const Symbol& root) {
  return SearchSyntaxTree(root, NodekNetVariable());
}

std::vector<verible::TreeSearchMatch> FindAllRegisterVariables(
    const Symbol& root) {
  return SearchSyntaxTree(root, NodekRegisterVariable());
}

std::vector<verible::TreeSearchMatch> FindAllGateInstances(const Symbol& root) {
  return SearchSyntaxTree(root, NodekGateInstance());
}

// Don't want to expose kInstantiationBase because it is an artificial grouping.
static const SyntaxTreeNode& GetInstantiationBaseFromDataDeclaration(
    const Symbol& data_declaration) {
  return GetSubtreeAsNode(data_declaration, NodeEnum::kDataDeclaration, 1,
                          NodeEnum::kInstantiationBase);
}

const SyntaxTreeNode* GetQualifiersOfDataDeclaration(
    const Symbol& data_declaration) {
  const auto* quals =
      GetSubtreeAsSymbol(data_declaration, NodeEnum::kDataDeclaration, 0);
  return verible::CheckOptionalSymbolAsNode(quals, NodeEnum::kQualifierList);
}

const SyntaxTreeNode& GetTypeOfDataDeclaration(const Symbol& data_declaration) {
  return GetSubtreeAsNode(
      GetInstantiationBaseFromDataDeclaration(data_declaration),
      NodeEnum::kInstantiationBase, 0);
}

const SyntaxTreeNode& GetInstanceListFromDataDeclaration(
    const Symbol& data_declaration) {
  return GetSubtreeAsNode(
      GetInstantiationBaseFromDataDeclaration(data_declaration),
      NodeEnum::kInstantiationBase, 1);
}

const SyntaxTreeNode& GetReferenceCallBaseFromInstantiationType(
    const Symbol& instantiation_type) {
  return GetSubtreeAsNode(instantiation_type, NodeEnum::kInstantiationType, 0);
}

const SyntaxTreeNode& GetReferenceFromReferenceCallBase(
    const Symbol& reference_call_base) {
  return GetSubtreeAsNode(reference_call_base, NodeEnum::kReferenceCallBase, 0);
}

const SyntaxTreeNode& GetLocalRootFromReference(const Symbol& reference) {
  return GetSubtreeAsNode(reference, NodeEnum::kReference, 0);
}

const SyntaxTreeNode& GetUnqualifiedIdFromLocalRoot(const Symbol& local_root) {
  return GetSubtreeAsNode(local_root, NodeEnum::kLocalRoot, 0);
}

const verible::TokenInfo& GetTypeTokenInfoFromDataDeclaration(
    const verible::Symbol& data_declaration) {
  const SyntaxTreeNode& instantiation_type =
      GetTypeOfDataDeclaration(data_declaration);
  const SyntaxTreeNode& reference_call_base =
      GetReferenceCallBaseFromInstantiationType(instantiation_type);
  const SyntaxTreeNode& reference =
      GetReferenceFromReferenceCallBase(reference_call_base);
  const SyntaxTreeNode& local_root = GetLocalRootFromReference(reference);
  const SyntaxTreeNode& unqualified_id =
      GetUnqualifiedIdFromLocalRoot(local_root);
  const verible::SyntaxTreeLeaf* instance_symbol_identifier =
      GetIdentifier(unqualified_id);
  return instance_symbol_identifier->get();
}

const verible::TokenInfo& GetModuleInstanceNameTokenInfoFromGateInstance(
    const verible::Symbol& gate_instance) {
  const verible::SyntaxTreeLeaf& instance_name =
      GetSubtreeAsLeaf(gate_instance, NodeEnum::kGateInstance, 0);
  return instance_name.get();
}

const verible::TokenInfo& GetInstanceNameTokenInfoFromRegisterVariable(
    const verible::Symbol& regiseter_variable) {
  const verible::SyntaxTreeLeaf& instance_name =
      GetSubtreeAsLeaf(regiseter_variable, NodeEnum::kRegisterVariable, 0);
  return instance_name.get();
}

}  // namespace verilog
