//===-- InternalNames.cpp -------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
//
//===----------------------------------------------------------------------===//

#include "flang/Optimizer/Support/InternalNames.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Diagnostics.h"
#include "llvm/Support/CommandLine.h"
#include <optional>
#include <regex>

static llvm::cl::opt<std::string> mainEntryName(
    "main-entry-name",
    llvm::cl::desc("override the name of the default PROGRAM entry (may be "
                   "helpful for using other runtimes)"));

constexpr std::int64_t badValue = -1;

inline std::string prefix() { return "_Q"; }

/// Generate a mangling prefix from module, submodule, procedure, and
/// statement function names, plus an (innermost) block scope id.
static std::string doAncestors(llvm::ArrayRef<llvm::StringRef> modules,
                               llvm::ArrayRef<llvm::StringRef> procs,
                               std::int64_t blockId = 0) {
  std::string prefix;
  const char *tag = "M";
  for (auto mod : modules) {
    prefix.append(tag).append(mod.lower());
    tag = "S";
  }
  for (auto proc : procs)
    prefix.append("F").append(proc.lower());
  if (blockId)
    prefix.append("B").append(std::to_string(blockId));
  return prefix;
}

inline llvm::SmallVector<llvm::StringRef>
convertToStringRef(llvm::ArrayRef<std::string> from) {
  return {from.begin(), from.end()};
}

inline std::optional<llvm::StringRef>
convertToStringRef(const std::optional<std::string> &from) {
  std::optional<llvm::StringRef> to;
  if (from)
    to = *from;
  return to;
}

static std::string readName(llvm::StringRef uniq, std::size_t &i,
                            std::size_t init, std::size_t end) {
  // Allow 'X' to be part of the mangled name, which
  // can happen after the special symbols are replaced
  // in the mangled names by CompilerGeneratedNamesConversionPass.
  for (i = init; i < end && (uniq[i] < 'A' || uniq[i] > 'Z' || uniq[i] == 'X');
       ++i) {
    // do nothing
  }
  return uniq.substr(init, i - init).str();
}

static std::int64_t readInt(llvm::StringRef uniq, std::size_t &i,
                            std::size_t init, std::size_t end) {
  for (i = init; i < end && uniq[i] >= '0' && uniq[i] <= '9'; ++i) {
    // do nothing
  }
  std::int64_t result = badValue;
  if (uniq.substr(init, i - init).getAsInteger(10, result))
    return badValue;
  return result;
}

std::string fir::NameUniquer::toLower(llvm::StringRef name) {
  return name.lower();
}

std::string fir::NameUniquer::intAsString(std::int64_t i) {
  assert(i >= 0);
  return std::to_string(i);
}

std::string fir::NameUniquer::doKind(std::int64_t kind) {
  std::string result = "K";
  if (kind < 0)
    return result.append("N").append(intAsString(-kind));
  return result.append(intAsString(kind));
}

std::string fir::NameUniquer::doKinds(llvm::ArrayRef<std::int64_t> kinds) {
  std::string result;
  for (auto i : kinds)
    result.append(doKind(i));
  return result;
}

std::string fir::NameUniquer::doCommonBlock(llvm::StringRef name) {
  return prefix().append("C").append(toLower(name));
}

std::string
fir::NameUniquer::doConstant(llvm::ArrayRef<llvm::StringRef> modules,
                             llvm::ArrayRef<llvm::StringRef> procs,
                             std::int64_t blockId, llvm::StringRef name) {
  return prefix()
      .append(doAncestors(modules, procs, blockId))
      .append("EC")
      .append(toLower(name));
}

std::string
fir::NameUniquer::doDispatchTable(llvm::ArrayRef<llvm::StringRef> modules,
                                  llvm::ArrayRef<llvm::StringRef> procs,
                                  std::int64_t blockId, llvm::StringRef name,
                                  llvm::ArrayRef<std::int64_t> kinds) {
  return prefix()
      .append(doAncestors(modules, procs, blockId))
      .append("DT")
      .append(toLower(name))
      .append(doKinds(kinds));
}

std::string fir::NameUniquer::doGenerated(llvm::StringRef name) {
  return prefix().append("Q").append(name);
}

std::string
fir::NameUniquer::doGenerated(llvm::ArrayRef<llvm::StringRef> modules,
                              llvm::ArrayRef<llvm::StringRef> procs,
                              std::int64_t blockId, llvm::StringRef name) {
  return prefix()
      .append("Q")
      .append(doAncestors(modules, procs, blockId))
      .append(name);
}

std::string fir::NameUniquer::doIntrinsicTypeDescriptor(
    llvm::ArrayRef<llvm::StringRef> modules,
    llvm::ArrayRef<llvm::StringRef> procs, std::int64_t blockId,
    IntrinsicType type, std::int64_t kind) {
  const char *name = nullptr;
  switch (type) {
  case IntrinsicType::CHARACTER:
    name = "character";
    break;
  case IntrinsicType::COMPLEX:
    name = "complex";
    break;
  case IntrinsicType::INTEGER:
    name = "integer";
    break;
  case IntrinsicType::LOGICAL:
    name = "logical";
    break;
  case IntrinsicType::REAL:
    name = "real";
    break;
  }
  assert(name && "unknown intrinsic type");
  return prefix()
      .append(doAncestors(modules, procs, blockId))
      .append("YI")
      .append(name)
      .append(doKind(kind));
}

std::string
fir::NameUniquer::doProcedure(llvm::ArrayRef<llvm::StringRef> modules,
                              llvm::ArrayRef<llvm::StringRef> procs,
                              llvm::StringRef name) {
  return prefix()
      .append(doAncestors(modules, procs))
      .append("P")
      .append(toLower(name));
}

std::string fir::NameUniquer::doType(llvm::ArrayRef<llvm::StringRef> modules,
                                     llvm::ArrayRef<llvm::StringRef> procs,
                                     std::int64_t blockId, llvm::StringRef name,
                                     llvm::ArrayRef<std::int64_t> kinds) {
  return prefix()
      .append(doAncestors(modules, procs, blockId))
      .append("T")
      .append(toLower(name))
      .append(doKinds(kinds));
}

std::string
fir::NameUniquer::doTypeDescriptor(llvm::ArrayRef<llvm::StringRef> modules,
                                   llvm::ArrayRef<llvm::StringRef> procs,
                                   std::int64_t blockId, llvm::StringRef name,
                                   llvm::ArrayRef<std::int64_t> kinds) {
  return prefix()
      .append(doAncestors(modules, procs, blockId))
      .append("CT")
      .append(toLower(name))
      .append(doKinds(kinds));
}

std::string
fir::NameUniquer::doTypeDescriptor(llvm::ArrayRef<std::string> modules,
                                   llvm::ArrayRef<std::string> procs,
                                   std::int64_t blockId, llvm::StringRef name,
                                   llvm::ArrayRef<std::int64_t> kinds) {
  auto rmodules = convertToStringRef(modules);
  auto rprocs = convertToStringRef(procs);
  return doTypeDescriptor(rmodules, rprocs, blockId, name, kinds);
}

std::string
fir::NameUniquer::doVariable(llvm::ArrayRef<llvm::StringRef> modules,
                             llvm::ArrayRef<llvm::StringRef> procs,
                             std::int64_t blockId, llvm::StringRef name) {
  return prefix()
      .append(doAncestors(modules, procs, blockId))
      .append("E")
      .append(toLower(name));
}

std::string
fir::NameUniquer::doNamelistGroup(llvm::ArrayRef<llvm::StringRef> modules,
                                  llvm::ArrayRef<llvm::StringRef> procs,
                                  llvm::StringRef name) {
  return prefix()
      .append(doAncestors(modules, procs))
      .append("N")
      .append(toLower(name));
}

llvm::StringRef fir::NameUniquer::doProgramEntry() {
  if (mainEntryName.size())
    return mainEntryName;
  return "_QQmain";
}

std::pair<fir::NameUniquer::NameKind, fir::NameUniquer::DeconstructedName>
fir::NameUniquer::deconstruct(llvm::StringRef uniq) {
  uniq = fir::NameUniquer::dropTypeConversionMarkers(uniq);
  if (uniq.starts_with("_Q")) {
    llvm::SmallVector<std::string> modules;
    llvm::SmallVector<std::string> procs;
    std::int64_t blockId = 0;
    std::string name;
    llvm::SmallVector<std::int64_t> kinds;
    NameKind nk = NameKind::NOT_UNIQUED;
    for (std::size_t i = 2, end{uniq.size()}; i != end;) {
      switch (uniq[i]) {
      case 'B': // Block
        blockId = readInt(uniq, i, i + 1, end);
        break;
      case 'C': // Common block
        nk = NameKind::COMMON;
        name = readName(uniq, i, i + 1, end);
        break;
      case 'D': // Dispatch table
        nk = NameKind::DISPATCH_TABLE;
        assert(uniq[i + 1] == 'T');
        name = readName(uniq, i, i + 2, end);
        break;
      case 'E':
        if (uniq[i + 1] == 'C') { // Constant Entity
          nk = NameKind::CONSTANT;
          name = readName(uniq, i, i + 2, end);
        } else { // variable Entity
          nk = NameKind::VARIABLE;
          name = readName(uniq, i, i + 1, end);
        }
        break;
      case 'F': // procedure/Function ancestor component of a mangled prefix
        procs.push_back(readName(uniq, i, i + 1, end));
        break;
      case 'K':
        if (uniq[i + 1] == 'N') // Negative Kind
          kinds.push_back(-readInt(uniq, i, i + 2, end));
        else // [positive] Kind
          kinds.push_back(readInt(uniq, i, i + 1, end));
        break;
      case 'M': // Module
      case 'S': // Submodule
        modules.push_back(readName(uniq, i, i + 1, end));
        break;
      case 'N': // Namelist group
        nk = NameKind::NAMELIST_GROUP;
        name = readName(uniq, i, i + 1, end);
        break;
      case 'P': // Procedure/function (itself)
        nk = NameKind::PROCEDURE;
        name = readName(uniq, i, i + 1, end);
        break;
      case 'Q': // UniQue mangle name tag
        nk = NameKind::GENERATED;
        name = uniq;
        i = end;
        break;
      case 'T': // derived Type
        nk = NameKind::DERIVED_TYPE;
        name = readName(uniq, i, i + 1, end);
        break;
      case 'Y':
        if (uniq[i + 1] == 'I') { // tYpe descriptor for an Intrinsic type
          nk = NameKind::INTRINSIC_TYPE_DESC;
          name = readName(uniq, i, i + 1, end);
        } else { // tYpe descriptor
          nk = NameKind::TYPE_DESC;
          name = readName(uniq, i, i + 2, end);
        }
        break;
      default:
        assert(false && "unknown uniquing code");
        break;
      }
    }
    return {nk, DeconstructedName(modules, procs, blockId, name, kinds)};
  }
  return {NameKind::NOT_UNIQUED, DeconstructedName(uniq)};
}

bool fir::NameUniquer::isExternalFacingUniquedName(
    const std::pair<fir::NameUniquer::NameKind,
                    fir::NameUniquer::DeconstructedName> &deconstructResult) {
  return (deconstructResult.first == NameKind::PROCEDURE ||
          deconstructResult.first == NameKind::COMMON) &&
         deconstructResult.second.modules.empty() &&
         deconstructResult.second.procs.empty();
}

bool fir::NameUniquer::needExternalNameMangling(llvm::StringRef uniquedName) {
  auto result = fir::NameUniquer::deconstruct(uniquedName);
  return result.first != fir::NameUniquer::NameKind::NOT_UNIQUED &&
         fir::NameUniquer::isExternalFacingUniquedName(result);
}

bool fir::NameUniquer::belongsToModule(llvm::StringRef uniquedName,
                                       llvm::StringRef moduleName) {
  auto result = fir::NameUniquer::deconstruct(uniquedName);
  return !result.second.modules.empty() &&
         result.second.modules[0] == moduleName;
}

/// Flang records the lexical module/submodule nesting of a symbol in the
/// uniqued root produced by \c fir::NameUniquer; \c deconstruct exposes that
/// as \c parts.modules. A non-empty module path means the symbol was declared
/// under a module or submodule, not only at program or internal unit scope.
/// We then require \c VARIABLE, \c CONSTANT, or \c COMMON so we match
/// module-level data (including common), not procedures or other name kinds
/// that can also carry a module prefix.
bool fir::NameUniquer::isModuleScopeDataUniquedName(
    llvm::StringRef uniquedName) {
  auto [kind, parts] = fir::NameUniquer::deconstruct(uniquedName);
  if (parts.modules.empty())
    return false;

  switch (kind) {
  case fir::NameUniquer::NameKind::VARIABLE:
  case fir::NameUniquer::NameKind::CONSTANT:
  case fir::NameUniquer::NameKind::COMMON:
    return true;
  default:
    return false;
  }
}

static std::string
mangleTypeDescriptorKinds(llvm::ArrayRef<std::int64_t> kinds) {
  if (kinds.empty())
    return "";
  std::string result;
  for (std::int64_t kind : kinds)
    result += (fir::kNameSeparator + std::to_string(kind)).str();
  return result;
}

static std::string getDerivedTypeObjectName(llvm::StringRef mangledTypeName,
                                            const llvm::StringRef separator) {
  mangledTypeName =
      fir::NameUniquer::dropTypeConversionMarkers(mangledTypeName);
  auto result = fir::NameUniquer::deconstruct(mangledTypeName);
  if (result.first != fir::NameUniquer::NameKind::DERIVED_TYPE)
    return "";
  std::string varName = separator.str() + result.second.name +
                        mangleTypeDescriptorKinds(result.second.kinds);
  llvm::SmallVector<llvm::StringRef> modules;
  for (const std::string &mod : result.second.modules)
    modules.push_back(mod);
  llvm::SmallVector<llvm::StringRef> procs;
  for (const std::string &proc : result.second.procs)
    procs.push_back(proc);
  return fir::NameUniquer::doVariable(modules, procs, result.second.blockId,
                                      varName);
}

std::string
fir::NameUniquer::getTypeDescriptorName(llvm::StringRef mangledTypeName) {
  return getDerivedTypeObjectName(mangledTypeName,
                                  fir::kTypeDescriptorSeparator);
}

std::string fir::NameUniquer::getTypeDescriptorAssemblyName(
    llvm::StringRef mangledTypeName) {
  return replaceSpecialSymbols(getTypeDescriptorName(mangledTypeName));
}

std::string fir::NameUniquer::getTypeDescriptorBindingTableName(
    llvm::StringRef mangledTypeName) {
  return getDerivedTypeObjectName(mangledTypeName, fir::kBindingTableSeparator);
}

std::string
fir::NameUniquer::getComponentInitName(llvm::StringRef mangledTypeName,
                                       llvm::StringRef componentName) {

  std::string prefix =
      getDerivedTypeObjectName(mangledTypeName, fir::kComponentInitSeparator);
  return (prefix + fir::kNameSeparator + componentName).str();
}

llvm::StringRef
fir::NameUniquer::dropTypeConversionMarkers(llvm::StringRef mangledTypeName) {
  if (mangledTypeName.ends_with(fir::boxprocSuffix))
    return mangledTypeName.drop_back(fir::boxprocSuffix.size());
  return mangledTypeName;
}

std::string fir::NameUniquer::replaceSpecialSymbols(const std::string &name) {
  return std::regex_replace(name, std::regex{"\\."}, "X");
}

bool fir::NameUniquer::isSpecialSymbol(llvm::StringRef name) {
  return !name.empty() && (name[0] == '.' || name[0] == 'X');
}
