// 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

#include <nanobind/intrusive/counter.h>

#include <memory>
#include <nanobind/intrusive/counter.inl>

#include "./binding.h"
#include "./hal.h"
#include "./invoke.h"
#include "./io.h"
#include "./loop.h"
#include "./py_module.h"
#include "./status_utils.h"
#include "./tokenizer.h"
#include "./vm.h"
#include "iree/base/tooling/flags.h"
#include "iree/hal/drivers/init.h"

namespace {
// Stable storage for flag processing.  Flag handling uses string views,
// expecting the caller to keep the original strings around for as long
// as the flags are in use.  This object holds one set of flag strings
// for each invocation of parse_flags.
std::vector<std::unique_ptr<std::vector<std::string>>> alloced_flag_cache;
}  // namespace

namespace iree {
namespace python {

NB_MODULE(_runtime, m) {
  IREE_TRACE_APP_ENTER();

  IREE_CHECK_OK(iree_hal_register_all_available_drivers(
      iree_hal_driver_registry_default()));

  m.doc() = "IREE Binding Backend Helpers";
  SetupHalBindings(m);
  SetupInvokeBindings(m);
  SetupIoBindings(m);
  SetupLoopBindings(m);
  SetupPyModuleBindings(m);
  SetupTokenizerBindings(m);
  SetupVmBindings(m);

  // Adds the given set of strings to the global flags.  These new flags
  // take effect upon the next creation of a driver.  They do not affect
  // drivers already created.
  m.def("parse_flags", [](py::args py_flags) {
    // Make a new set of strings at the back of the cache
    alloced_flag_cache.emplace_back(
        std::make_unique<std::vector<std::string>>(std::vector<std::string>()));
    auto& alloced_flags = *alloced_flag_cache.back();

    // Add the given python strings to the std::string set.
    alloced_flags.push_back("python");
    for (py::handle py_flag : py_flags) {
      alloced_flags.push_back(py::cast<std::string>(py_flag));
    }

    // As the flags-processing mechanism of the C API requires long-lived
    // char * strings, create a set of char * strings from the std::strings,
    // with the std::strings responsible for maintaining the storage.
    // Must build pointer vector after filling std::strings so pointers are
    // stable.
    std::vector<char*> flag_ptrs;
    for (auto& alloced_flag : alloced_flags) {
      flag_ptrs.push_back(const_cast<char*>(alloced_flag.c_str()));
    }

    // Send the flags to the C API
    char** argv = &flag_ptrs[0];
    int argc = flag_ptrs.size();
    CheckApiStatus(iree_flags_parse(IREE_FLAGS_PARSE_MODE_CONTINUE_AFTER_HELP,
                                    &argc, &argv),
                   "Error parsing flags");
  });

  m.def("disable_leak_checker", []() { py::set_leak_warnings(false); });

  py::intrusive_init(
      [](PyObject* o) noexcept {
        py::gil_scoped_acquire guard;
        Py_INCREF(o);
      },
      [](PyObject* o) noexcept {
        py::gil_scoped_acquire guard;
        Py_DECREF(o);
      });
}

}  // namespace python
}  // namespace iree
