// Copyright (C) 2020 The Android Open Source Project
//
// Licensed 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.
#pragma once
#include "dctv.h"
#include "pyutil.h"

namespace dctv {

// "Interface" for an exception that can set the current
// Python exception.
struct PyException : virtual std::exception {
  // Set the stored exception as the Python current exception.
  // Must be repeatable.
  virtual void set_pyexception() const noexcept = 0;
  // std::exception::what implementation that formats the
  // Python exception.
  const char* what() const noexcept override;
 private:
  // Cache of the what() message; C++17 gives us noexcept init.
  mutable String msg;
};

struct PyExceptionInfo {
  unique_pyref type, value, traceback;

  static PyExceptionInfo fetch() noexcept;
  void normalize() noexcept;
  void restore() && noexcept;
  PyExceptionInfo dup() const noexcept;
};

// AutoErrorSentinel means _exceptions_to_pyerr should use the
// value-initialized version of the return type of functor, e.g., if
// functor returns a PyObject*, then the error value is PyObject*(),
// i.e., (PyObject*)nullptr.  If functor returns void,
// _exceptions_to_pyerr also returns void.  We use an enum class so
// that it's legal for AutoErrorSentinel to be a non-type template
// parameter before C++20.
enum class AutoErrorSentinel {};

// Set the currently-pending C++ exception as a Python exception.
// Type erasure for exception setting: keeps the generated
// _exceptions_to_pyerr code small.
void _set_pending_cxx_exception_as_pyexception() noexcept;

// Call FUNCTOR with no arguments and return whatever it returns.
// If FUNCTOR throws instead of returning, convert the exception to a
// Python exception, set it as current, and return the error sentinel.
// The error sentinel defaults to the value-initialized version of
// FUNCTOR's return value, but can be overridden by passing the
// ERROR_SENTINEL parameter.
template<typename Functor, typename ErrorSentinel = AutoErrorSentinel>
auto _exceptions_to_pyerr(
    Functor&& functor,
    ErrorSentinel error_sentinel = ErrorSentinel())
    noexcept;

// Figure out the plain-C type we should accept in the wrapper to
// build objects of type T.
template<typename T, typename = void>
struct py_fn_arg_decay;

template<typename T>
struct py_fn_arg_decay<
  T,
  typename std::enable_if_t<std::is_arithmetic_v<T> ||
                            std::is_pointer_v<T>>>
{
  using plain_c_type = T;
  static T convert(plain_c_type value) { return value; }
};

template<typename T>
struct py_fn_arg_decay<
  obj_pyref<T>,
  typename std::enable_if_t<is_safe_pycast<PyObject, T>()>>
{
  using plain_c_type = PyObject*;
  static obj_pyref<T> convert(plain_c_type value) {
    return pyref(value).as<T>();
  }
};

// Abstract over the difference between function pointers and member
// function pointers and provide invocation wrappers.  If Munge1st is
// true, treat the first argument as a self pointer.
// TODO(dancol): rename Munge1st to Arg1IsSelf.
template<bool Munge1st, typename R, typename T, typename... Args>
struct base_py_fn_info {
  using first_argument_type =
      typename std::conditional_t<Munge1st, PyObject*, T*>;
  using args_tuple_type = std::tuple<T*, Args...>;
  using delegate_type = R(*)(args_tuple_type) noexcept;
  template<delegate_type Delegate>
  static auto plain_c_wrapper(
      first_argument_type obj,
      typename py_fn_arg_decay<Args>::plain_c_type... args) noexcept;
};

template<bool Munge1st, typename Function>
struct py_fn_info;

template<bool Munge1st, typename R, typename T, typename... Args>
struct py_fn_info<Munge1st, R(*)(T*, Args...)>
    : base_py_fn_info<Munge1st, R, T, Args...> {
  static constexpr bool is_noexcept = false;
};

template<bool Munge1st, typename R, typename T, typename... Args>
struct py_fn_info<Munge1st, R(*)(T*, Args...) noexcept>
    : base_py_fn_info<Munge1st, R, T, Args...> {
  static constexpr bool is_noexcept = true;
};

template<bool Munge1st, typename R, typename T, typename... Args>
struct py_fn_info<Munge1st, R(T::*)(Args...)>
    : base_py_fn_info<Munge1st, R, T, Args...> {
  static constexpr bool is_noexcept = false;
};

template<bool Munge1st, typename R, typename T, typename... Args>
struct py_fn_info<Munge1st, R(T::*)(Args...) noexcept>
    : base_py_fn_info<Munge1st, R, T, Args...> {
  static constexpr bool is_noexcept = true;
};

template<bool Munge1st, typename R, typename T, typename... Args>
struct py_fn_info<Munge1st, R(T::*)(Args...) const >
    : base_py_fn_info<Munge1st, R, T, Args...> {
  static constexpr bool is_noexcept = false;
};

template<bool Munge1st, typename R, typename T, typename... Args>
struct py_fn_info<Munge1st, R(T::*)(Args...) const noexcept>
    : base_py_fn_info<Munge1st, R, T, Args...> {
  static constexpr bool is_noexcept = true;
};

template<typename FunctionType,
         typename ErrorSentinelType,
         bool Munge1st>
struct _py_error_wrapper {
  using info = py_fn_info<Munge1st, FunctionType>;
  template<FunctionType Function, ErrorSentinelType ErrorSentinel>
  struct wrapper {
    static auto delegate(typename info::args_tuple_type args_tuple) noexcept;
    static constexpr auto function = &info::template plain_c_wrapper<delegate>;
  };
};

template<auto Function,
         auto ErrorSentinel = AutoErrorSentinel(),
         bool Munge1st = true>
constexpr auto wraperr();

struct PyExceptionSaver final : NoCopy, NoMove {
  inline PyExceptionSaver() noexcept;
  inline ~PyExceptionSaver() noexcept;
 private:
  PyExceptionInfo info;
};

inline void init_pyerr(pyref m) {};

}  // namespace dctv

#include "pyerr-inl.h"
