//===-- CharacterRuntime.cpp -- runtime for CHARACTER type entities -------===//
//
// 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 "flang/Lower/CharacterRuntime.h"
#include "RTBuilder.h"
#include "flang/Lower/Bridge.h"
#include "flang/Lower/CharacterExpr.h"
#include "flang/Lower/FIRBuilder.h"
#include "flang/Runtime/character.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"

using namespace Fortran::runtime;

#define NAMIFY_HELPER(X) #X
#define NAMIFY(X) NAMIFY_HELPER(IONAME(X))
#define mkRTKey(X) mkKey(RTNAME(X))

namespace Fortran::lower {
/// Static table of CHARACTER runtime calls
///
/// This logical map contains the name and type builder function for each
/// runtime function listed in the tuple. This table is fully constructed at
/// compile-time. Use the `mkRTKey` macro to access the table.
static constexpr std::tuple<
    mkRTKey(CharacterCompareScalar), mkRTKey(CharacterCompareScalar1),
    mkRTKey(CharacterCompareScalar2), mkRTKey(CharacterCompareScalar4),
    mkRTKey(CharacterCompare)>
    newCharRTTable;
} // namespace Fortran::lower

using namespace Fortran::lower;

/// Helper function to retrieve the name of the IO function given the key `A`
template <typename A>
static constexpr const char *getName() {
  return std::get<A>(newCharRTTable).name;
}

/// Helper function to retrieve the type model signature builder of the IO
/// function as defined by the key `A`
template <typename A>
static constexpr FuncTypeBuilderFunc getTypeModel() {
  return std::get<A>(newCharRTTable).getTypeModel();
}

inline int64_t getLength(mlir::Type argTy) {
  return argTy.cast<fir::SequenceType>().getShape()[0];
}

/// Get (or generate) the MLIR FuncOp for a given runtime function.
template <typename E>
static mlir::FuncOp getRuntimeFunc(mlir::Location loc,
                                   Fortran::lower::FirOpBuilder &builder) {
  auto name = getName<E>();
  auto func = builder.getNamedFunction(name);
  if (func)
    return func;
  auto funTy = getTypeModel<E>()(builder.getContext());
  func = builder.createFunction(loc, name, funTy);
  func->setAttr("fir.runtime", builder.getUnitAttr());
  return func;
}

/// Helper function to recover the KIND from the FIR type.
static int discoverKind(mlir::Type ty) {
  if (auto charTy = ty.dyn_cast<fir::CharacterType>())
    return charTy.getFKind();
  if (auto eleTy = fir::dyn_cast_ptrEleTy(ty))
    return discoverKind(eleTy);
  if (auto arrTy = ty.dyn_cast<fir::SequenceType>())
    return discoverKind(arrTy.getEleTy());
  if (auto boxTy = ty.dyn_cast<fir::BoxCharType>())
    return discoverKind(boxTy.getEleTy());
  if (auto boxTy = ty.dyn_cast<fir::BoxType>())
    return discoverKind(boxTy.getEleTy());
  llvm_unreachable("unexpected character type");
}

//===----------------------------------------------------------------------===//
// Lower character operations
//===----------------------------------------------------------------------===//

mlir::Value Fortran::lower::genRawCharCompare(
    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
    mlir::arith::CmpIPredicate cmp, mlir::Value lhsBuff, mlir::Value lhsLen,
    mlir::Value rhsBuff, mlir::Value rhsLen) {
  auto &builder = converter.getFirOpBuilder();
  mlir::FuncOp beginFunc;
  switch (discoverKind(lhsBuff.getType())) {
  case 1:
    beginFunc = getRuntimeFunc<mkRTKey(CharacterCompareScalar1)>(loc, builder);
    break;
  case 2:
    beginFunc = getRuntimeFunc<mkRTKey(CharacterCompareScalar2)>(loc, builder);
    break;
  case 4:
    beginFunc = getRuntimeFunc<mkRTKey(CharacterCompareScalar4)>(loc, builder);
    break;
  default:
    llvm_unreachable("runtime does not support CHARACTER KIND");
  }
  auto fTy = beginFunc.getType();
  auto lptr = builder.createConvert(loc, fTy.getInput(0), lhsBuff);
  auto llen = builder.createConvert(loc, fTy.getInput(2), lhsLen);
  auto rptr = builder.createConvert(loc, fTy.getInput(1), rhsBuff);
  auto rlen = builder.createConvert(loc, fTy.getInput(3), rhsLen);
  llvm::SmallVector<mlir::Value, 4> args = {lptr, rptr, llen, rlen};
  auto tri = builder.create<mlir::CallOp>(loc, beginFunc, args).getResult(0);
  auto zero = builder.createIntegerConstant(loc, tri.getType(), 0);
  return builder.create<mlir::arith::CmpIOp>(loc, cmp, tri, zero);
}

mlir::Value Fortran::lower::genBoxCharCompare(
    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
    mlir::arith::CmpIPredicate cmp, mlir::Value lhs, mlir::Value rhs) {
  auto &builder = converter.getFirOpBuilder();
  Fortran::lower::CharacterExprHelper helper{builder, loc};
  auto lhsPair = helper.materializeCharacter(lhs);
  auto rhsPair = helper.materializeCharacter(rhs);
  return genRawCharCompare(converter, loc, cmp, lhsPair.first, lhsPair.second,
                           rhsPair.first, rhsPair.second);
}
