#include "testing.h"
#include "../../lib/Evaluate/host.h"
#include "../../lib/Evaluate/intrinsics-library-templates.h"
#include "flang/Evaluate/call.h"
#include "flang/Evaluate/expression.h"
#include "flang/Evaluate/fold.h"
#include "flang/Evaluate/intrinsics.h"
#include "flang/Evaluate/tools.h"
#include <tuple>

using namespace Fortran::evaluate;

// helper to call functions on all types from tuple
template <typename... T> struct RunOnTypes {};
template <typename Test, typename... T>
struct RunOnTypes<Test, std::tuple<T...>> {
  static void Run() { (..., Test::template Run<T>()); }
};

// test for fold.h GetScalarConstantValue function
struct TestGetScalarConstantValue {
  template <typename T> static void Run() {
    Expr<T> exprFullyTyped{Constant<T>{Scalar<T>{}}};
    Expr<SomeKind<T::category>> exprSomeKind{exprFullyTyped};
    Expr<SomeType> exprSomeType{exprSomeKind};
    TEST(GetScalarConstantValue<T>(exprFullyTyped).has_value());
    TEST(GetScalarConstantValue<T>(exprSomeKind).has_value());
    TEST(GetScalarConstantValue<T>(exprSomeType).has_value());
  }
};

template <typename T>
static FunctionRef<T> CreateIntrinsicElementalCall(
    const std::string &name, const Expr<T> &arg) {
  Fortran::semantics::Attrs attrs;
  attrs.set(Fortran::semantics::Attr::ELEMENTAL);
  ActualArguments args{ActualArgument{AsGenericExpr(arg)}};
  ProcedureDesignator intrinsic{
      SpecificIntrinsic{name, T::GetType(), 0, attrs}};
  return FunctionRef<T>{std::move(intrinsic), std::move(args)};
}

// Test flushSubnormalsToZero when folding with host runtime.
// Subnormal value flushing on host is handle in host.cpp
// HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment

// Dummy host runtime functions where subnormal flushing matters
float SubnormalFlusher1(float f) { // given f is subnormal
  return 2.3 * f; // returns 0 if subnormal arguments are flushed to zero
}

float SubnormalFlusher2(float f) { // given f/2 is subnormal
  return f / 2.3; // returns 0 if subnormal
}

void TestHostRuntimeSubnormalFlushing() {
  using R4 = Type<TypeCategory::Real, 4>;
  if constexpr (std::is_same_v<host::HostType<R4>, float>) {
    Fortran::parser::CharBlock src;
    Fortran::parser::ContextualMessages messages{src, nullptr};
    Fortran::common::IntrinsicTypeDefaultKinds defaults;
    auto intrinsics{Fortran::evaluate::IntrinsicProcTable::Configure(defaults)};
    FoldingContext flushingContext{
        messages, defaults, intrinsics, defaultRounding, true};
    FoldingContext noFlushingContext{
        messages, defaults, intrinsics, defaultRounding, false};

    HostIntrinsicProceduresLibrary lib;
    lib.AddProcedure(HostRuntimeIntrinsicProcedure{
        "flusher_test1", SubnormalFlusher1, true});
    lib.AddProcedure(HostRuntimeIntrinsicProcedure{
        "flusher_test2", SubnormalFlusher2, true});

    // Test subnormal argument flushing
    if (auto callable{
            lib.GetHostProcedureWrapper<Scalar, R4, R4>("flusher_test1")}) {
      // Biggest IEEE 32bits subnormal power of two
      host::HostType<R4> input1{5.87747175411144e-39};
      const Scalar<R4> x1{host::CastHostToFortran<R4>(input1)};
      Scalar<R4> y1Flushing{callable.value()(flushingContext, x1)};
      Scalar<R4> y1NoFlushing{callable.value()(noFlushingContext, x1)};
      TEST(y1Flushing.IsZero());
      TEST(!y1NoFlushing.IsZero());
    } else {
      TEST(false);
    }
    // Test subnormal result flushing
    if (auto callable{
            lib.GetHostProcedureWrapper<Scalar, R4, R4>("flusher_test2")}) {
      // Smallest (positive) non-subnormal IEEE 32 bit float value
      host::HostType<R4> input2{1.1754944e-38};
      const Scalar<R4> x2{host::CastHostToFortran<R4>(input2)};
      Scalar<R4> y2Flushing{callable.value()(flushingContext, x2)};
      Scalar<R4> y2NoFlushing{callable.value()(noFlushingContext, x2)};
      TEST(y2Flushing.IsZero());
      TEST(!y2NoFlushing.IsZero());
    } else {
      TEST(false);
    }
  } else {
    TEST(false); // Cannot run this test on the host
  }
}

int main() {
  RunOnTypes<TestGetScalarConstantValue, AllIntrinsicTypes>::Run();
  TestHostRuntimeSubnormalFlushing();
  return testing::Complete();
}
