//===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Unit tests for CodeGenAction.
//
//===----------------------------------------------------------------------===//

#include "mlir/IR/Builders.h"
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendActions.h"
#include "flang/Frontend/TextDiagnosticPrinter.h"

#include "gtest/gtest.h"

#include <memory>

using namespace Fortran::frontend;

namespace test {
class DummyDialect : public ::mlir::Dialect {
  explicit DummyDialect(::mlir::MLIRContext *context)
      : ::mlir::Dialect(getDialectNamespace(), context,
            ::mlir::TypeID::get<DummyDialect>()) {
    initialize();
  }

  void initialize();
  friend class ::mlir::MLIRContext;

public:
  ~DummyDialect() override = default;
  static constexpr ::llvm::StringLiteral getDialectNamespace() {
    return ::llvm::StringLiteral("dummy");
  }
};

namespace dummy {
class FakeOp : public ::mlir::Op<FakeOp> {
public:
  using Op::Op;

  static llvm::StringRef getOperationName() { return "dummy.fake"; }

  static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames() { return {}; }

  static void build(
      ::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState) {}

  static FakeOp create(
      ::mlir::OpBuilder &odsBuilder, ::mlir::Location location) {
    ::mlir::OperationState state(location, getOperationName());
    build(odsBuilder, state);
    auto res = ::llvm::dyn_cast<FakeOp>(odsBuilder.create(state));
    assert(res && "builder didn't return the right type");
    return res;
  }
};
} // namespace dummy
} // namespace test

MLIR_DECLARE_EXPLICIT_TYPE_ID(::test::DummyDialect)
MLIR_DEFINE_EXPLICIT_TYPE_ID(::test::DummyDialect)

namespace test {

void DummyDialect::initialize() { addOperations<::test::dummy::FakeOp>(); }
} // namespace test

// A test CodeGenAction to verify that we gracefully handle failure to convert
// from MLIR to LLVM IR.
class LLVMConversionFailureCodeGenAction : public CodeGenAction {
public:
  LLVMConversionFailureCodeGenAction()
      : CodeGenAction(BackendActionTy::Backend_EmitLL) {
    mlirCtx = std::make_unique<mlir::MLIRContext>();
    mlirCtx->loadDialect<test::DummyDialect>();

    mlir::Location loc(mlir::UnknownLoc::get(mlirCtx.get()));
    mlirModule = mlir::ModuleOp::create(loc, "mod");

    mlir::OpBuilder builder(mlirCtx.get());
    builder.setInsertionPointToStart(&mlirModule->getRegion().front());
    // Create a fake op to trip conversion to LLVM.
    test::dummy::FakeOp::create(builder, loc);

    llvmCtx = std::make_unique<llvm::LLVMContext>();
  }
};

TEST(CodeGenAction, GracefullyHandleLLVMConversionFailure) {
  std::string diagnosticOutput;
  llvm::raw_string_ostream diagnosticsOS(diagnosticOutput);
  clang::DiagnosticOptions diagOpts;
  auto diagPrinter = std::make_unique<Fortran::frontend::TextDiagnosticPrinter>(
      diagnosticsOS, diagOpts);

  CompilerInstance ci;
  ci.createDiagnostics(diagPrinter.get(), /*ShouldOwnClient=*/false);
  ci.setInvocation(std::make_shared<CompilerInvocation>());
  ci.setOutputStream(std::make_unique<llvm::raw_null_ostream>());
  ci.getInvocation().getCodeGenOpts().OptimizationLevel = 0;

  FrontendInputFile file("/dev/null", InputKind());

  LLVMConversionFailureCodeGenAction action;
  action.setInstance(&ci);
  action.setCurrentInput(file);

  consumeError(action.execute());
  ASSERT_EQ(diagnosticOutput,
      "error: Lowering to LLVM IR failed\n"
      "error: failed to create the LLVM module\n");
}
