// 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/type.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());
}

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

// 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* GetInstantiationTypeOfDataDeclaration(
    const Symbol& data_declaration) {
  const auto* base = GetInstantiationBaseFromDataDeclaration(data_declaration);
  if (!base) return nullptr;
  return GetSubtreeAsNode(*base, NodeEnum::kInstantiationBase, 0);
}

const SyntaxTreeNode* GetInstanceListFromDataDeclaration(
    const Symbol& data_declaration) {
  const auto* base = GetInstantiationBaseFromDataDeclaration(data_declaration);
  if (!base) return nullptr;
  return GetSubtreeAsNode(*base, NodeEnum::kInstantiationBase, 1);
}

const verible::SyntaxTreeNode* GetParamListFromDataDeclaration(
    const verible::Symbol& data_declaration) {
  const SyntaxTreeNode* instantiation_type =
      GetInstantiationTypeOfDataDeclaration(data_declaration);
  if (!instantiation_type) return nullptr;
  return GetParamListFromInstantiationType(*instantiation_type);
}

const verible::TokenInfo* GetModuleInstanceNameTokenInfoFromGateInstance(
    const verible::Symbol& gate_instance) {
  const verible::SyntaxTreeLeaf* instance_name =
      GetSubtreeAsLeaf(gate_instance, NodeEnum::kGateInstance, 0);
  if (!instance_name) return nullptr;
  return &instance_name->get();
}

const verible::TokenInfo* GetInstanceNameTokenInfoFromRegisterVariable(
    const verible::Symbol& regiseter_variable) {
  const verible::SyntaxTreeLeaf* instance_name =
      GetSubtreeAsLeaf(regiseter_variable, NodeEnum::kRegisterVariable, 0);
  if (!instance_name) return nullptr;
  return &instance_name->get();
}

const verible::SyntaxTreeNode* GetParenGroupFromModuleInstantiation(
    const verible::Symbol& gate_instance) {
  return GetSubtreeAsNode(gate_instance, NodeEnum::kGateInstance, 2,
                          NodeEnum::kParenGroup);
}

const verible::SyntaxTreeLeaf*
GetUnqualifiedIdFromVariableDeclarationAssignment(
    const verible::Symbol& variable_declaration_assign) {
  const verible::Symbol* identifier = GetSubtreeAsSymbol(
      variable_declaration_assign, NodeEnum::kVariableDeclarationAssignment, 0);
  if (!identifier) return nullptr;
  if (identifier->Kind() == verible::SymbolKind::kLeaf) {
    // This is a workaround for the below:
    // TODO(fangism): remove this condition after fixing the issue for "branch".
    // "riscv_instr          branch;"
    // issue on github: https://github.com/chipsalliance/verible/issues/547
    return &verible::SymbolCastToLeaf(*identifier);
  }
  return AutoUnwrapIdentifier(*identifier);
}

const verible::SyntaxTreeNode*
GetTrailingExpressionFromVariableDeclarationAssign(
    const verible::Symbol& variable_declaration_assign) {
  const Symbol* trailing_expression = GetSubtreeAsSymbol(
      variable_declaration_assign, NodeEnum::kVariableDeclarationAssignment, 2);
  return verible::CheckOptionalSymbolAsNode(trailing_expression,
                                            NodeEnum::kTrailingAssign);
}

const verible::SyntaxTreeNode* GetTrailingExpressionFromRegisterVariable(
    const verible::Symbol& register_variable) {
  const Symbol* trailing_expression =
      GetSubtreeAsSymbol(register_variable, NodeEnum::kRegisterVariable, 2);
  return verible::CheckOptionalSymbolAsNode(trailing_expression,
                                            NodeEnum::kTrailingAssign);
}

const verible::SyntaxTreeNode* GetPackedDimensionFromDataDeclaration(
    const verible::Symbol& data_declaration) {
  const verible::SyntaxTreeNode* instantiation_type =
      GetInstantiationTypeOfDataDeclaration(data_declaration);
  if (!instantiation_type) return nullptr;
  const verible::Symbol* data_type = verible::GetSubtreeAsSymbol(
      *instantiation_type, NodeEnum::kInstantiationType, 0);
  if (data_type == nullptr) return nullptr;

  return GetPackedDimensionFromDataType(*data_type);
}

const verible::SyntaxTreeNode* GetUnpackedDimensionFromRegisterVariable(
    const verible::Symbol& register_variable) {
  return verible::GetSubtreeAsNode(register_variable,
                                   NodeEnum::kRegisterVariable, 1,
                                   NodeEnum::kUnpackedDimensions);
}

const verible::SyntaxTreeNode*
GetUnpackedDimensionFromVariableDeclarationAssign(
    const verible::Symbol& variable_declaration_assign) {
  return verible::GetSubtreeAsNode(variable_declaration_assign,
                                   NodeEnum::kVariableDeclarationAssignment, 1,
                                   NodeEnum::kUnpackedDimensions);
}

const verible::Symbol* GetTypeIdentifierFromDataDeclaration(
    const verible::Symbol& data_declaration) {
  const SyntaxTreeNode* instantiation_type =
      GetInstantiationTypeOfDataDeclaration(data_declaration);
  if (!instantiation_type) return nullptr;
  const verible::Symbol* identifier =
      GetTypeIdentifierFromInstantiationType(*instantiation_type);
  if (identifier != nullptr) {
    return identifier;
  }

  const verible::Symbol* base_type =
      GetBaseTypeFromInstantiationType(*instantiation_type);
  if (base_type == nullptr) return nullptr;
  return GetTypeIdentifierFromBaseType(*base_type);
}

const verible::SyntaxTreeNode* GetStructOrUnionOrEnumTypeFromDataDeclaration(
    const verible::Symbol& data_declaration) {
  const SyntaxTreeNode* instantiation_type =
      GetInstantiationTypeOfDataDeclaration(data_declaration);
  if (!instantiation_type) return nullptr;
  return GetStructOrUnionOrEnumTypeFromInstantiationType(*instantiation_type);
}

}  // namespace verilog
