// Copyright 2019 The IREE Authors
//
// Licensed 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

#ifndef IREE_BINDINGS_PYTHON_IREE_RT_VM_H_
#define IREE_BINDINGS_PYTHON_IREE_RT_VM_H_

#include <optional>

#include "./binding.h"
#include "./status_utils.h"
#include "iree/base/api.h"
#include "iree/vm/api.h"
#include "iree/vm/bytecode_module.h"
#include "iree/vm/ref.h"

namespace iree {
namespace python {

class FunctionAbi;

//------------------------------------------------------------------------------
// Retain/release bindings
//------------------------------------------------------------------------------

template <>
struct ApiPtrAdapter<iree_vm_buffer_t> {
  static void Retain(iree_vm_buffer_t* b) { iree_vm_buffer_retain(b); }
  static void Release(iree_vm_buffer_t* b) { iree_vm_buffer_release(b); }
};

template <>
struct ApiPtrAdapter<iree_vm_instance_t> {
  static void Retain(iree_vm_instance_t* b) { iree_vm_instance_retain(b); }
  static void Release(iree_vm_instance_t* b) { iree_vm_instance_release(b); }
};

template <>
struct ApiPtrAdapter<iree_vm_context_t> {
  static void Retain(iree_vm_context_t* b) { iree_vm_context_retain(b); }
  static void Release(iree_vm_context_t* b) { iree_vm_context_release(b); }
};

template <>
struct ApiPtrAdapter<iree_vm_list_t> {
  static void Retain(iree_vm_list_t* b) { iree_vm_list_retain(b); }
  static void Release(iree_vm_list_t* b) { iree_vm_list_release(b); }
};

template <>
struct ApiPtrAdapter<iree_vm_module_t> {
  static void Retain(iree_vm_module_t* b) { iree_vm_module_retain(b); }
  static void Release(iree_vm_module_t* b) { iree_vm_module_release(b); }
};

template <>
struct ApiPtrAdapter<iree_vm_invocation_t> {
  static void Retain(iree_vm_invocation_t* b) { iree_vm_invocation_retain(b); }
  static void Release(iree_vm_invocation_t* b) {
    iree_vm_invocation_release(b);
  }
};

template <>
struct ApiPtrAdapter<iree_vm_ref_t> {
  static void Retain(iree_vm_ref_t* b) {
    iree_vm_ref_t out_ref;
    std::memset(&out_ref, 0, sizeof(out_ref));
    iree_vm_ref_retain(b, &out_ref);
  }
  static void Release(iree_vm_ref_t* b) { iree_vm_ref_release(b); }
};

//------------------------------------------------------------------------------
// VmBuffer
//------------------------------------------------------------------------------

class VmBuffer : public ApiRefCounted<VmBuffer, iree_vm_buffer_t> {};

//------------------------------------------------------------------------------
// VmVariantList
// TODO: Rename to VmList
//------------------------------------------------------------------------------

class VmVariantList : public ApiRefCounted<VmVariantList, iree_vm_list_t> {
 public:
  static VmVariantList Create(iree_host_size_t capacity) {
    iree_vm_list_t* list;
    CheckApiStatus(iree_vm_list_create(/*element_type=*/nullptr, capacity,
                                       iree_allocator_system(), &list),
                   "Error allocating variant list");
    return VmVariantList::StealFromRawPtr(list);
  }

  iree_host_size_t size() const { return iree_vm_list_size(raw_ptr()); }

  void AppendNullRef() {
    iree_vm_ref_t null_ref = {0};
    CheckApiStatus(iree_vm_list_push_ref_move(raw_ptr(), &null_ref),
                   "Error appending to list");
  }

  std::string DebugString() const;
  void PushFloat(double fvalue);
  void PushInt(int64_t ivalue);
  void PushList(VmVariantList& other);
  void PushRef(py::handle ref_or_object);
  py::object GetAsList(int index);
  py::object GetAsRef(int index);
  py::object GetAsObject(int index, py::object clazz);
  py::object GetVariant(int index);
  py::object GetAsSerializedTraceValue(int index);
};

//------------------------------------------------------------------------------
// VmInstance
//------------------------------------------------------------------------------

class VmInstance : public ApiRefCounted<VmInstance, iree_vm_instance_t> {
 public:
  static VmInstance Create();
};

//------------------------------------------------------------------------------
// VmModule
//------------------------------------------------------------------------------

class VmModule : public ApiRefCounted<VmModule, iree_vm_module_t> {
 public:
  static VmModule FromFlatbufferBlob(py::object flatbuffer_blob_object);

  std::optional<iree_vm_function_t> LookupFunction(
      const std::string& name, iree_vm_function_linkage_t linkage);

  std::string name() const {
    auto name_sv = iree_vm_module_name(raw_ptr());
    return std::string(name_sv.data, name_sv.size);
  }

  py::object get_stashed_flatbuffer_blob() { return stashed_flatbuffer_blob; }

 private:
  // If the module was created from a FlatBuffer blob, we stash it here.
  py::object stashed_flatbuffer_blob = py::none();
};

//------------------------------------------------------------------------------
// VmContext
//------------------------------------------------------------------------------

class VmContext : public ApiRefCounted<VmContext, iree_vm_context_t> {
 public:
  // Creates a context, optionally with modules, which will make the context
  // static, disallowing further module registration (and may be more
  // efficient).
  static VmContext Create(VmInstance* instance,
                          std::optional<std::vector<VmModule*>> modules);

  // Registers additional modules. Only valid for non static contexts (i.e.
  // those created without modules.
  void RegisterModules(std::vector<VmModule*> modules);

  // Unique id for this context.
  int context_id() const { return iree_vm_context_id(raw_ptr()); }

  // Synchronously invokes the given function.
  void Invoke(iree_vm_function_t f, VmVariantList& inputs,
              VmVariantList& outputs);
};

class VmInvocation : public ApiRefCounted<VmInvocation, iree_vm_invocation_t> {
};

//------------------------------------------------------------------------------
// VmRef (represents a pointer to an arbitrary reference object).
//------------------------------------------------------------------------------

class VmRef {
 public:
  //----------------------------------------------------------------------------
  // Binds the reference protocol to a VmRefObject bound class.
  // This defines three attributes:
  //   __iree_vm_type_id__()
  //        Gets the type id from the object.
  //   [readonly property] __iree_vm_ref__ :
  //        Gets a VmRef from the object.
  //   __iree_vm_cast__(ref) :
  //        Dereferences the VmRef to the concrete type. Returns None on cast
  //        failure.
  //
  // In addition, a user attribute of "ref" will be added that is an alias of
  // __iree_vm_ref__.
  //
  // An __eq__ method is added which returns true if the python objects refer
  // to the same vm object.
  //
  // The BindRefProtocol() helper is used on a py::class_ defined for a
  // reference object. It takes some of the C helper functions that are defined
  // for each type and is generic.
  //----------------------------------------------------------------------------
  static const char* const kTypeIdAttr;
  static const char* const kRefAttr;
  static const char* const kCastAttr;

  template <typename PyClass, typename TypeIdFunctor, typename RetainRefFunctor,
            typename DerefFunctor, typename IsaFunctor>
  static void BindRefProtocol(PyClass& cls, TypeIdFunctor type_id,
                              RetainRefFunctor retain_ref, DerefFunctor deref,
                              IsaFunctor isa) {
    using WrapperType = typename PyClass::type;
    using RawPtrType = typename WrapperType::RawPtrType;
    auto ref_lambda = [=](WrapperType& self) {
      return VmRef::Steal(retain_ref(self.raw_ptr()));
    };
    cls.def_static(VmRef::kTypeIdAttr, [=]() { return type_id(); });
    cls.def_property_readonly(VmRef::kRefAttr, ref_lambda);
    cls.def_property_readonly("ref", ref_lambda);
    cls.def_static(VmRef::kCastAttr, [=](VmRef& ref) -> py::object {
      if (!isa(ref.ref())) {
        return py::none();
      }
      return py::cast(WrapperType::BorrowFromRawPtr(deref(ref.ref())),
                      py::return_value_policy::move);
    });
    cls.def("__eq__", [](WrapperType& self, WrapperType& other) {
      return self.raw_ptr() == other.raw_ptr();
    });
    cls.def("__eq__",
            [](WrapperType& self, py::object& other) { return false; });
  }

  // Initializes a null ref.
  VmRef() { std::memset(&ref_, 0, sizeof(ref_)); }
  VmRef(VmRef&& other) : ref_(other.ref_) {
    std::memset(&other.ref_, 0, sizeof(other.ref_));
  }
  VmRef(const VmRef&) = delete;
  VmRef& operator=(const VmRef&) = delete;
  ~VmRef() {
    if (ref_.ptr) {
      iree_vm_ref_release(&ref_);
    }
  }

  // Creates a VmRef from an owned ref, taking the reference count.
  static VmRef Steal(iree_vm_ref_t ref) { return VmRef(ref); }

  iree_vm_ref_t& ref() { return ref_; }

  py::object Deref(py::object ref_object_class, bool optional);
  bool IsInstance(py::object ref_object_class);

  std::string ToString();

 private:
  // Initializes with an owned ref.
  VmRef(iree_vm_ref_t ref) : ref_(ref) {}
  iree_vm_ref_t ref_;
};

void SetupVmBindings(pybind11::module m);

}  // namespace python
}  // namespace iree

#endif  // IREE_BINDINGS_PYTHON_IREE_RT_VM_H_
