//===-- SymbolInfo.cpp - Symbol Info ----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "SymbolInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"

using llvm::yaml::MappingTraits;
using ContextType = clang::find_all_symbols::SymbolInfo::ContextType;
using clang::find_all_symbols::SymbolInfo;
using clang::find_all_symbols::SymbolAndSignals;
using SymbolKind = clang::find_all_symbols::SymbolInfo::SymbolKind;

LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(SymbolAndSignals)
LLVM_YAML_IS_SEQUENCE_VECTOR(SymbolInfo::Context)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<SymbolAndSignals> {
  static void mapping(IO &io, SymbolAndSignals &Symbol) {
    io.mapRequired("Name", Symbol.Symbol.Name);
    io.mapRequired("Contexts", Symbol.Symbol.Contexts);
    io.mapRequired("FilePath", Symbol.Symbol.FilePath);
    io.mapRequired("Type", Symbol.Symbol.Type);
    io.mapRequired("Seen", Symbol.Signals.Seen);
    io.mapRequired("Used", Symbol.Signals.Used);
  }
};

template <> struct ScalarEnumerationTraits<ContextType> {
  static void enumeration(IO &io, ContextType &value) {
    io.enumCase(value, "Record", ContextType::Record);
    io.enumCase(value, "Namespace", ContextType::Namespace);
    io.enumCase(value, "EnumDecl", ContextType::EnumDecl);
  }
};

template <> struct ScalarEnumerationTraits<SymbolKind> {
  static void enumeration(IO &io, SymbolKind &value) {
    io.enumCase(value, "Variable", SymbolKind::Variable);
    io.enumCase(value, "Function", SymbolKind::Function);
    io.enumCase(value, "Class", SymbolKind::Class);
    io.enumCase(value, "TypedefName", SymbolKind::TypedefName);
    io.enumCase(value, "EnumDecl", SymbolKind::EnumDecl);
    io.enumCase(value, "EnumConstantDecl", SymbolKind::EnumConstantDecl);
    io.enumCase(value, "Macro", SymbolKind::Macro);
    io.enumCase(value, "Unknown", SymbolKind::Unknown);
  }
};

template <> struct MappingTraits<SymbolInfo::Context> {
  static void mapping(IO &io, SymbolInfo::Context &Context) {
    io.mapRequired("ContextType", Context.first);
    io.mapRequired("ContextName", Context.second);
  }
};

} // namespace yaml
} // namespace llvm

namespace clang {
namespace find_all_symbols {

SymbolInfo::SymbolInfo(llvm::StringRef Name, SymbolKind Type,
                       llvm::StringRef FilePath,
                       const std::vector<Context> &Contexts)
    : Name(Name), Type(Type), FilePath(FilePath), Contexts(Contexts) {}

bool SymbolInfo::operator==(const SymbolInfo &Symbol) const {
  return std::tie(Name, Type, FilePath, Contexts) ==
         std::tie(Symbol.Name, Symbol.Type, Symbol.FilePath, Symbol.Contexts);
}

bool SymbolInfo::operator<(const SymbolInfo &Symbol) const {
  return std::tie(Name, Type, FilePath, Contexts) <
         std::tie(Symbol.Name, Symbol.Type, Symbol.FilePath, Symbol.Contexts);
}

std::string SymbolInfo::getQualifiedName() const {
  std::string QualifiedName = Name;
  for (const auto &Context : Contexts) {
    if (Context.first == ContextType::EnumDecl)
      continue;
    QualifiedName = Context.second + "::" + QualifiedName;
  }
  return QualifiedName;
}

SymbolInfo::Signals &SymbolInfo::Signals::operator+=(const Signals &RHS) {
  Seen += RHS.Seen;
  Used += RHS.Used;
  return *this;
}

SymbolInfo::Signals SymbolInfo::Signals::operator+(const Signals &RHS) const {
  Signals Result = *this;
  Result += RHS;
  return Result;
}

bool SymbolInfo::Signals::operator==(const Signals &RHS) const {
  return std::tie(Seen, Used) == std::tie(RHS.Seen, RHS.Used);
}

bool SymbolAndSignals::operator==(const SymbolAndSignals& RHS) const {
  return std::tie(Symbol, Signals) == std::tie(RHS.Symbol, RHS.Signals);
}

bool WriteSymbolInfosToStream(llvm::raw_ostream &OS,
                              const SymbolInfo::SignalMap &Symbols) {
  llvm::yaml::Output yout(OS);
  for (const auto &Symbol : Symbols) {
    SymbolAndSignals S{Symbol.first, Symbol.second};
    yout << S;
  }
  return true;
}

std::vector<SymbolAndSignals> ReadSymbolInfosFromYAML(llvm::StringRef Yaml) {
  std::vector<SymbolAndSignals> Symbols;
  llvm::yaml::Input yin(Yaml);
  yin >> Symbols;
  return Symbols;
}

} // namespace find_all_symbols
} // namespace clang
