// Copyright 2021 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/tools/ls/document-symbol-filler.h"

#include "common/lsp/lsp-protocol-enums.h"
#include "common/lsp/lsp-protocol.h"
#include "common/util/value_saver.h"
#include "verilog/CST/class.h"
#include "verilog/CST/functions.h"
#include "verilog/CST/module.h"
#include "verilog/CST/package.h"
#include "verilog/CST/seq_block.h"

// Magic value to hint that we have to fill out the start range.
static constexpr int kUninitializedStartLine = -1;

namespace verilog {
DocumentSymbolFiller::DocumentSymbolFiller(
    bool kate_workaround, const verible::TextStructureView &text,
    verible::lsp::DocumentSymbol *toplevel)
    : kModuleSymbolKind(kate_workaround ? verible::lsp::SymbolKind::Method
                                        : verible::lsp::SymbolKind::Module),
      kBlockSymbolKind(kate_workaround ? verible::lsp::SymbolKind::Class
                                       : verible::lsp::SymbolKind::Namespace),
      text_view_(text),
      current_symbol_(toplevel) {
  toplevel->range.start = {.line = 0, .character = 0};
}

void DocumentSymbolFiller::Visit(const verible::SyntaxTreeLeaf &leaf) {
  verible::lsp::Range range = RangeFromLeaf(leaf);
  if (current_symbol_->range.start.line == kUninitializedStartLine) {
    // We're the first concrete token with a position within our parent,
    // set the start position.
    current_symbol_->range.start = range.start;
  }
  // Update the end position with every token we see. The last one wins.
  current_symbol_->range.end = range.end;
}

void DocumentSymbolFiller::Visit(const verible::SyntaxTreeNode &node) {
  verible::lsp::DocumentSymbol *parent = current_symbol_;

  // These things can probably be done easier with Matchers.
  verible::lsp::DocumentSymbol node_symbol;
  node_symbol.range.start.line = kUninitializedStartLine;
  bool is_visible_node = false;
  switch (static_cast<verilog::NodeEnum>(node.Tag().tag)) {
    case verilog::NodeEnum::kModuleDeclaration: {
      const auto *name_leaf = verilog::GetModuleName(node);
      if (name_leaf) {
        is_visible_node = true;
        node_symbol.kind = kModuleSymbolKind;
        node_symbol.selectionRange = RangeFromLeaf(*name_leaf);
        node_symbol.name = std::string(name_leaf->get().text());
      }
      break;
    }

    case verilog::NodeEnum::kSeqBlock:
    case verilog::NodeEnum::kGenerateBlock:
      if (!node.children().empty()) {
        const auto &begin = node.children().front().get();
        if (begin) {
          if (const auto *token = GetBeginLabelTokenInfo(*begin); token) {
            is_visible_node = true;
            node_symbol.kind = kBlockSymbolKind;
            node_symbol.selectionRange = RangeFromToken(*token);
            node_symbol.name = std::string(token->text());
          }
        }
      }
      break;

    case verilog::NodeEnum::kClassDeclaration: {
      const auto *class_name_leaf = verilog::GetClassName(node);
      if (class_name_leaf) {
        is_visible_node = true;
        node_symbol.kind = verible::lsp::SymbolKind::Class;
        node_symbol.selectionRange = RangeFromToken(class_name_leaf->get());
        node_symbol.name = std::string(class_name_leaf->get().text());
      }
      break;
    }

    case verilog::NodeEnum::kPackageDeclaration: {
      const auto *package_name = verilog::GetPackageNameToken(node);
      if (package_name) {
        is_visible_node = true;
        node_symbol.kind = verible::lsp::SymbolKind::Package;
        node_symbol.selectionRange = RangeFromToken(*package_name);
        node_symbol.name = std::string(package_name->text());
      }
      break;
    }

    case verilog::NodeEnum::kFunctionDeclaration: {
      const auto &function_name = verilog::GetFunctionName(node);
      if (function_name) {
        is_visible_node = true;
        node_symbol.kind = verible::lsp::SymbolKind::Function;
        node_symbol.selectionRange = RangeFromToken(function_name->get());
        node_symbol.name = std::string(function_name->get().text());
      }
      break;
    }

    default:
      is_visible_node = false;
      break;
  }

  // Independent of visible or not, we always descend to our children.
  if (is_visible_node) {
    const verible::ValueSaver<verible::lsp::DocumentSymbol *> value_saver(
        &current_symbol_, &node_symbol);
    for (const auto &child : node.children()) {
      if (child) child->Accept(this);
    }
    // Update our parent with what we found
    if (parent->children == nullptr) {
      if (parent->range.start.line == kUninitializedStartLine) {
        parent->range.start = node_symbol.range.start;
      }
      parent->children = nlohmann::json::array();
      parent->has_children = true;
    }
    parent->children.push_back(node_symbol);
    parent->range.end = node_symbol.range.end;
  } else {
    for (const auto &child : node.children()) {
      if (child) child->Accept(this);
    }
  }
}

verible::lsp::Range DocumentSymbolFiller::RangeFromLeaf(
    const verible::SyntaxTreeLeaf &leaf) const {
  return RangeFromToken(leaf.get());
}

verible::lsp::Range DocumentSymbolFiller::RangeFromToken(
    const verible::TokenInfo &token) const {
  const verible::LineColumnRange range = text_view_.GetRangeForToken(token);
  return {.start = {.line = range.start.line, .character = range.start.column},
          .end = {.line = range.end.line, .character = range.end.column}};
}
}  // namespace verilog
