/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
#define TVM_FFI_DLL_EXPORT_INCLUDE_METADATA 1

#include <gtest/gtest.h>
#include <tvm/ffi/any.h>
#include <tvm/ffi/container/array.h>
#include <tvm/ffi/container/map.h>
#include <tvm/ffi/container/tensor.h>
#include <tvm/ffi/extra/json.h>
#include <tvm/ffi/function.h>
#include <tvm/ffi/memory.h>

#include "./testing_object.h"

namespace {

using namespace tvm::ffi;
using namespace tvm::ffi::testing;

TEST(Func, FromPacked) {
  Function fadd1 = Function::FromPacked([](const AnyView* args, int32_t num_args, Any* rv) {
    EXPECT_EQ(num_args, 1);
    int32_t a = args[0].cast<int32_t>();
    *rv = a + 1;
  });
  int b = fadd1(1).cast<int>();
  EXPECT_EQ(b, 2);

  Function fadd2 = Function::FromPacked([](const AnyView* args, int32_t num_args, Any* rv) {
    EXPECT_EQ(num_args, 1);
    auto a = args[0].cast<TInt>();
    EXPECT_EQ(a.use_count(), 2);
    *rv = a->value + 1;
  });
  EXPECT_EQ(fadd2(TInt(12)).cast<int>(), 13);
}

TEST(Func, PackedArgs) {
  Function fadd1 = Function::FromPacked([](PackedArgs args, Any* rv) {
    EXPECT_EQ(args.size(), 1);
    int32_t a = args[0].cast<int>();
    *rv = a + 1;
  });
  int b = fadd1(1).cast<int>();
  EXPECT_EQ(b, 2);

  Function fadd2 = Function::FromPacked([](PackedArgs args, Any* rv) {
    EXPECT_EQ(args.size(), 1);
    TInt a = args[0].cast<TInt>();
    EXPECT_EQ(a.use_count(), 2);
    *rv = a->value + 1;
  });
  EXPECT_EQ(fadd2(TInt(12)).cast<int>(), 13);

  TInt v(12);
  AnyView data[3];
  PackedArgs::Fill(data, 3, 1, v);
  EXPECT_EQ(data[0].cast<int>(), 3);
  EXPECT_EQ(data[1].cast<int>(), 1);
  EXPECT_EQ(data[2].cast<TInt>()->value, 12);
}

TEST(Func, FromTyped) {
  // try decution
  Function fadd1 = Function::FromTyped([](const int32_t& a) -> int { return a + 1; });
  int b = fadd1(1).cast<int>();
  EXPECT_EQ(b, 2);

  // convert that triggers error
  EXPECT_THROW(
      {
        try {
          fadd1(1.1);
        } catch (const Error& error) {
          EXPECT_EQ(error.kind(), "TypeError");
          EXPECT_EQ(error.message(),
                    "Mismatched type on argument #0 when calling: `(0: int) -> int`. "
                    "Expected `int` but got `float`");
          throw;
        }
      },
      ::tvm::ffi::Error);

  // convert that triggers error
  EXPECT_THROW(
      {
        try {
          fadd1();
        } catch (const Error& error) {
          EXPECT_EQ(error.kind(), "TypeError");
          EXPECT_EQ(error.message(),
                    "Mismatched number of arguments when calling: `(0: int) -> int`. "
                    "Expected 1 but got 0 arguments");
          throw;
        }
      },
      ::tvm::ffi::Error);

  // convert with DLTensor* triggers error
  EXPECT_THROW(
      {
        try {
          DLTensor dltensor;
          fadd1(&dltensor);
        } catch (const Error& error) {
          EXPECT_EQ(error.kind(), "TypeError");
          EXPECT_EQ(error.message(),
                    "Mismatched type on argument #0 when calling: `(0: int) -> int`. "
                    "Expected `int` but got `DLTensor*`");
          throw;
        }
      },
      ::tvm::ffi::Error);

  // try decution
  Function fpass_and_return = Function::FromTyped(
      // NOLINTNEXTLINE(performance-unnecessary-value-param)
      [](TInt x, int value, AnyView z) -> Function {
        EXPECT_EQ(x.use_count(), 2);
        EXPECT_EQ(x->value, value);
        if (auto opt = z.as<int>()) {
          EXPECT_EQ(value, *opt);
        }
        return Function::FromTyped([value](int x) -> int { return x + value; });
      },
      "fpass_and_return");
  TInt a(11);
  auto fret = fpass_and_return(std::move(a), 11, 11).cast<Function>();
  EXPECT_EQ(fret(12).cast<int>(), 23);

  EXPECT_THROW(
      {
        try {
          fpass_and_return();
        } catch (const Error& error) {
          EXPECT_EQ(error.kind(), "TypeError");
          EXPECT_EQ(error.message(),
                    "Mismatched number of arguments when calling: "
                    "`fpass_and_return(0: test.Int, 1: int, 2: AnyView) -> ffi.Function`. "
                    "Expected 3 but got 0 arguments");
          throw;
        }
      },
      ::tvm::ffi::Error);

  Function fconcact =
      Function::FromTyped([](const String& a, const String& b) -> String { return a + b; });
  EXPECT_EQ(fconcact("abc", "def").cast<String>(), "abcdef");
}

TEST(Func, PassReturnAny) {
  // NOLINTNEXTLINE(performance-unnecessary-value-param)
  Function fadd_one = Function::FromTyped([](Any a) -> Any { return a.cast<int>() + 1; });
  EXPECT_EQ(fadd_one(1).cast<int>(), 2);
}

TEST(Func, Global) {
  Function::SetGlobal("testing.add1",
                      Function::FromTyped([](const int32_t& a) -> int { return a + 1; }));
  auto fadd1 = Function::GetGlobalRequired("testing.add1");
  int b = fadd1(1).cast<int>();
  EXPECT_EQ(b, 2);
  auto fnot_exist = Function::GetGlobal("testing.not_existing_func");
  EXPECT_TRUE(!fnot_exist);

  auto fname_functor =  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
      Function::GetGlobal("ffi.FunctionListGlobalNamesFunctor").value()().cast<Function>();
  Array<String> names;
  int len = fname_functor(-1).cast<int>();
  for (int i = 0; i < len; ++i) {
    names.push_back(fname_functor(i).cast<String>());
  }
  EXPECT_TRUE(std::find(names.begin(), names.end(), "testing.add1") != names.end());
}

TEST(Func, TypedFunction) {
  TypedFunction<int(int)> fadd1 = [](int a) -> int { return a + 1; };
  EXPECT_EQ(fadd1(1), 2);

  TypedFunction<int(int)> fadd2([](int a) -> int { return a + 2; });
  EXPECT_EQ(fadd2(1), 3);
  EXPECT_EQ(fadd2.packed()(1).cast<int>(), 3);

  TypedFunction<void(int)> fcheck_int;
  EXPECT_TRUE(fcheck_int == nullptr);
  fcheck_int = [](int a) -> void { EXPECT_EQ(a, 1); };
  fcheck_int(1);
}

TEST(Func, TypedFunctionAsAny) {
  TypedFunction<int(int)> fadd1 = [](int a) -> int { return a + 1; };
  Any fany(std::move(fadd1));
  EXPECT_TRUE(fadd1 == nullptr);  // NOLINT(bugprone-use-after-move,clang-analyzer-cplusplus.Move)
  auto fadd1_dup = fany.cast<TypedFunction<int(int)>>();
  EXPECT_EQ(fadd1_dup(1), 2);
}

TEST(Func, TypedFunctionAsAnyView) {
  TypedFunction<int(int)> fadd2 = [](int a) -> int { return a + 2; };
  AnyView fview(fadd2);
  auto fadd2_dup = fview.cast<TypedFunction<int(int)>>();
  EXPECT_EQ(fadd2_dup(1), 3);
}

TEST(Func, ObjectRefWithFallbackTraits) {
  // test cases to test automatic type conversion via ObjectRefWithFallbackTraits
  // through TPrimExpr
  Function freturn_primexpr = Function::FromTyped([](TPrimExpr a) -> TPrimExpr { return a; });

  auto result_int = freturn_primexpr(1).cast<TPrimExpr>();
  EXPECT_EQ(result_int->dtype, "int64");
  EXPECT_EQ(result_int->value, 1);

  // Test case for float
  auto result_float = freturn_primexpr(2.5).cast<TPrimExpr>();
  EXPECT_EQ(result_float->dtype, "float32");
  EXPECT_EQ(result_float->value, 2.5);

  // Test case for bool
  auto result_bool = freturn_primexpr(true).cast<TPrimExpr>();
  EXPECT_EQ(result_bool->dtype, "bool");
  EXPECT_EQ(result_bool->value, 1);

  // Test case for string
  auto result_string = freturn_primexpr("test_string").cast<TPrimExpr>();
  EXPECT_EQ(result_string->dtype, "test_string");
  EXPECT_EQ(result_string->value, 0);

  EXPECT_THROW(
      {
        try {
          freturn_primexpr(TInt(1));
        } catch (const Error& error) {
          EXPECT_EQ(error.kind(), "TypeError");
          EXPECT_EQ(
              error.message(),
              "Mismatched type on argument #0 when calling: `(0: test.PrimExpr) -> test.PrimExpr`. "
              "Expected `test.PrimExpr` but got `test.Int`");
          throw;
        }
      },
      ::tvm::ffi::Error);
}

TEST(SetRaisedFromCStr, ValueError) {
  TVMFFIErrorSetRaisedFromCStr("ValueError", "Value must be non-negative, got -5");
  Error error = tvm::ffi::details::MoveFromSafeCallRaised();
  EXPECT_EQ(error.kind(), "ValueError");
  EXPECT_EQ(error.message(), "Value must be non-negative, got -5");
}

TEST(SetRaisedFromCStrParts, TypeError) {
  const char* message_parts[] = {"Mismatched", nullptr, " got Tensor"};
  TVMFFIErrorSetRaisedFromCStrParts("TypeError", message_parts, 3);
  Error error = tvm::ffi::details::MoveFromSafeCallRaised();
  EXPECT_EQ(error.kind(), "TypeError");
  EXPECT_EQ(error.message(), "Mismatched got Tensor");
}

int testing_add1(int x) { return x + 1; }

TVM_FFI_DLL_EXPORT_TYPED_FUNC(testing_add1, testing_add1)

TEST(Func, FromExternC) {
  // this is the function abi convention
  Function fadd1 = Function::FromExternC(nullptr, __tvm_ffi_testing_add1, nullptr);
  EXPECT_EQ(fadd1(1).cast<int>(), 2);
}

int invoke_testing_add1(int x) {
  return Function::InvokeExternC(nullptr, __tvm_ffi_testing_add1, x).cast<int>();
}

TEST(Func, InvokeExternC) { EXPECT_EQ(invoke_testing_add1(1), 2); }

extern "C" int __tvm_ffi__metadata_testing_add1(void*, const TVMFFIAny*, int32_t, TVMFFIAny*);

TEST(Func, StaticLinkingMetadata) {
  String metadata_str =
      Function::InvokeExternC(nullptr, __tvm_ffi__metadata_testing_add1).cast<String>();
  Map<String, Any> metadata = json::Parse(metadata_str).cast<Map<String, Any>>();
  EXPECT_TRUE(metadata.count("type_schema"));
  std::string type_schema_str = metadata["type_schema"].cast<String>();
  EXPECT_TRUE(type_schema_str.find("int") != std::string::npos);
}

extern "C" TVM_FFI_DLL int TVMFFITestingDummyTarget();

TEST(Func, DummyCFunc) {
  int value = TVMFFITestingDummyTarget();
  EXPECT_EQ(value, 0);
}

}  // namespace
