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

#include <memory>
#include <string>
#include <vector>

#include "absl/container/node_hash_map.h"
#include "absl/strings/string_view.h"
#include "common/analysis/line_lint_rule.h"
#include "common/analysis/syntax_tree_lint_rule.h"
#include "common/analysis/text_structure_lint_rule.h"
#include "common/analysis/token_stream_lint_rule.h"
#include "common/util/container_util.h"
#include "common/util/logging.h"
#include "verilog/analysis/descriptions.h"

namespace verilog {
namespace analysis {

using verible::LineLintRule;
using verible::SyntaxTreeLintRule;
using verible::TextStructureLintRule;
using verible::TokenStreamLintRule;
using verible::container::FindOrNull;

namespace {
// Used to export function local static pointer to avoid global variables
template <typename RuleType>
absl::node_hash_map<LintRuleId, LintRuleInfo<RuleType>>* GetLintRuleRegistry() {
  static auto* registry =
      new absl::node_hash_map<LintRuleId, LintRuleInfo<RuleType>>();
  return registry;
}

// LintRuleRegistry is a template for interacting with lint rule registries.
// It is expected to be implicitly instantiated for every LintRule type.
template <typename RuleType>
class LintRuleRegistry {
 public:
  // Create and returns an instance of RuleType identified by rule.
  // Returns nullptr if rule is not registered.
  static std::unique_ptr<RuleType> CreateLintRule(const LintRuleId& rule) {
    auto* create_func = FindOrNull(*GetLintRuleRegistry<RuleType>(), rule);
    if (create_func == nullptr) {
      return nullptr;
    } else {
      return (create_func->lint_rule_generator)();
    }
  }

  // Returns true if registry holds a LintRule named rule.
  static bool ContainsLintRule(const LintRuleId& rule) {
    const auto reg = GetLintRuleRegistry<RuleType>();
    return reg->find(rule) != reg->end();
  }

  // Returns a sequence of registered rule names.
  static std::vector<LintRuleId> GetRegisteredRulesNames() {
    const auto* registry = GetLintRuleRegistry<RuleType>();
    std::vector<LintRuleId> rule_ids;
    rule_ids.reserve(registry->size());
    for (const auto& rule_bundle : *registry) {
      rule_ids.push_back(rule_bundle.first);
    }
    return rule_ids;
  }

  // Registers a lint rule with the appropriate registry.
  static void Register(const LintDescriptionFun& descriptor,
                       const LintRuleGeneratorFun<RuleType>& creator) {
    LintRuleInfo<RuleType> info;
    info.lint_rule_generator = creator;
    info.description = descriptor;
    (*GetLintRuleRegistry<RuleType>())[descriptor().name] = info;
  }

  // Returns the description of the specific rule, formatted for description
  // type passed in.
  static LintRuleDescriptor GetRuleDescription(const LintRuleId& rule) {
    auto* create_func = FindOrNull(*GetLintRuleRegistry<RuleType>(), rule);
    return (ABSL_DIE_IF_NULL(create_func)->description)();
  }

  // Adds each rule name and a struct of information describing the rule to the
  // map passed in.
  static void GetRegisteredRuleDescriptions(LintRuleDescriptionsMap* rule_map) {
    const auto* registry = GetLintRuleRegistry<RuleType>();
    for (const auto& rule_bundle : *registry) {
      (*rule_map)[rule_bundle.first].descriptor =
          GetRuleDescription(rule_bundle.first);
    }
  }

  LintRuleRegistry() = delete;
  LintRuleRegistry(const LintRuleRegistry&) = delete;
  LintRuleRegistry& operator=(const LintRuleRegistry&) = delete;
};

}  // namespace

template <typename RuleType>
LintRuleRegisterer<RuleType>::LintRuleRegisterer(
    const LintDescriptionFun& descriptor,
    const LintRuleGeneratorFun<RuleType>& creator) {
  LintRuleRegistry<RuleType>::Register(descriptor, creator);
}

bool IsRegisteredLintRule(const LintRuleId& rule_name) {
  return LintRuleRegistry<SyntaxTreeLintRule>::ContainsLintRule(rule_name) ||
         LintRuleRegistry<TokenStreamLintRule>::ContainsLintRule(rule_name) ||
         LintRuleRegistry<LineLintRule>::ContainsLintRule(rule_name) ||
         LintRuleRegistry<TextStructureLintRule>::ContainsLintRule(rule_name);
}

// The following functions are LintRule-type-specific:

std::vector<LintRuleId> RegisteredSyntaxTreeRulesNames() {
  return LintRuleRegistry<SyntaxTreeLintRule>::GetRegisteredRulesNames();
}

std::unique_ptr<SyntaxTreeLintRule> CreateSyntaxTreeLintRule(
    const LintRuleId& rule_name) {
  return LintRuleRegistry<SyntaxTreeLintRule>::CreateLintRule(rule_name);
}

std::vector<LintRuleId> RegisteredTokenStreamRulesNames() {
  return LintRuleRegistry<TokenStreamLintRule>::GetRegisteredRulesNames();
}

std::unique_ptr<TokenStreamLintRule> CreateTokenStreamLintRule(
    const LintRuleId& rule_name) {
  return LintRuleRegistry<TokenStreamLintRule>::CreateLintRule(rule_name);
}

std::vector<LintRuleId> RegisteredLineRulesNames() {
  return LintRuleRegistry<LineLintRule>::GetRegisteredRulesNames();
}

std::unique_ptr<LineLintRule> CreateLineLintRule(const LintRuleId& rule_name) {
  return LintRuleRegistry<LineLintRule>::CreateLintRule(rule_name);
}

std::vector<LintRuleId> RegisteredTextStructureRulesNames() {
  return LintRuleRegistry<TextStructureLintRule>::GetRegisteredRulesNames();
}

std::unique_ptr<TextStructureLintRule> CreateTextStructureLintRule(
    const LintRuleId& rule_name) {
  return LintRuleRegistry<TextStructureLintRule>::CreateLintRule(rule_name);
}

std::set<LintRuleId> GetAllRegisteredLintRuleNames() {
  std::set<LintRuleId> result;
  for (const auto name : RegisteredSyntaxTreeRulesNames()) {
    result.insert(name);
  }
  for (const auto name : RegisteredTokenStreamRulesNames()) {
    result.insert(name);
  }
  for (const auto name : RegisteredLineRulesNames()) {
    result.insert(name);
  }
  for (const auto name : RegisteredTextStructureRulesNames()) {
    result.insert(name);
  }
  return result;
}

LintRuleDescriptionsMap GetAllRuleDescriptions() {
  // Map that will hold the information to print about each rule.
  LintRuleDescriptionsMap res;
  LintRuleRegistry<SyntaxTreeLintRule>::GetRegisteredRuleDescriptions(&res);
  LintRuleRegistry<TokenStreamLintRule>::GetRegisteredRuleDescriptions(&res);
  LintRuleRegistry<LineLintRule>::GetRegisteredRuleDescriptions(&res);
  LintRuleRegistry<TextStructureLintRule>::GetRegisteredRuleDescriptions(&res);
  return res;
}

// Explicit template class instantiations
template class LintRuleRegisterer<LineLintRule>;
template class LintRuleRegisterer<SyntaxTreeLintRule>;
template class LintRuleRegisterer<TextStructureLintRule>;
template class LintRuleRegisterer<TokenStreamLintRule>;

}  // namespace analysis
}  // namespace verilog
