/*
    tests/test_buffers.cpp -- supporting Pythons' buffer protocol

    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#include <pybind11/complex.h>
#include <pybind11/stl.h>

#include "constructor_stats.h"
#include "pybind11_tests.h"

TEST_SUBMODULE(buffers, m) {
    m.attr("long_double_and_double_have_same_size") = (sizeof(long double) == sizeof(double));

    m.def("format_descriptor_format_buffer_info_equiv",
          [](const std::string &cpp_name, const py::buffer &buffer) {
              // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
              static auto *format_table = new std::map<std::string, std::string>;
              static auto *equiv_table
                  = new std::map<std::string, bool (py::buffer_info::*)() const>;
              if (format_table->empty()) {
#define PYBIND11_ASSIGN_HELPER(...)                                                               \
    (*format_table)[#__VA_ARGS__] = py::format_descriptor<__VA_ARGS__>::format();                 \
    (*equiv_table)[#__VA_ARGS__] = &py::buffer_info::item_type_is_equivalent_to<__VA_ARGS__>;
                  PYBIND11_ASSIGN_HELPER(PyObject *)
                  PYBIND11_ASSIGN_HELPER(bool)
                  PYBIND11_ASSIGN_HELPER(std::int8_t)
                  PYBIND11_ASSIGN_HELPER(std::uint8_t)
                  PYBIND11_ASSIGN_HELPER(std::int16_t)
                  PYBIND11_ASSIGN_HELPER(std::uint16_t)
                  PYBIND11_ASSIGN_HELPER(std::int32_t)
                  PYBIND11_ASSIGN_HELPER(std::uint32_t)
                  PYBIND11_ASSIGN_HELPER(std::int64_t)
                  PYBIND11_ASSIGN_HELPER(std::uint64_t)
                  PYBIND11_ASSIGN_HELPER(float)
                  PYBIND11_ASSIGN_HELPER(double)
                  PYBIND11_ASSIGN_HELPER(long double)
                  PYBIND11_ASSIGN_HELPER(std::complex<float>)
                  PYBIND11_ASSIGN_HELPER(std::complex<double>)
                  PYBIND11_ASSIGN_HELPER(std::complex<long double>)
#undef PYBIND11_ASSIGN_HELPER
              }
              return std::pair<std::string, bool>(
                  (*format_table)[cpp_name], (buffer.request().*((*equiv_table)[cpp_name]))());
          });

    // test_from_python / test_to_python:
    class Matrix {
    public:
        Matrix(py::ssize_t rows, py::ssize_t cols) : m_rows(rows), m_cols(cols) {
            print_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
            m_data = new float[(size_t) (rows * cols)];
            memset(m_data, 0, sizeof(float) * (size_t) (rows * cols));
        }

        Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) {
            print_copy_created(this,
                               std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
            m_data = new float[(size_t) (m_rows * m_cols)];
            memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));
        }

        Matrix(Matrix &&s) noexcept : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) {
            print_move_created(this);
            s.m_rows = 0;
            s.m_cols = 0;
            s.m_data = nullptr;
        }

        ~Matrix() {
            print_destroyed(this,
                            std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
            delete[] m_data;
        }

        Matrix &operator=(const Matrix &s) {
            if (this == &s) {
                return *this;
            }
            print_copy_assigned(this,
                                std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
            delete[] m_data;
            m_rows = s.m_rows;
            m_cols = s.m_cols;
            m_data = new float[(size_t) (m_rows * m_cols)];
            memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));
            return *this;
        }

        Matrix &operator=(Matrix &&s) noexcept {
            print_move_assigned(this,
                                std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
            if (&s != this) {
                delete[] m_data;
                m_rows = s.m_rows;
                m_cols = s.m_cols;
                m_data = s.m_data;
                s.m_rows = 0;
                s.m_cols = 0;
                s.m_data = nullptr;
            }
            return *this;
        }

        float operator()(py::ssize_t i, py::ssize_t j) const {
            return m_data[(size_t) (i * m_cols + j)];
        }

        float &operator()(py::ssize_t i, py::ssize_t j) {
            return m_data[(size_t) (i * m_cols + j)];
        }

        float *data() { return m_data; }

        py::ssize_t rows() const { return m_rows; }
        py::ssize_t cols() const { return m_cols; }

    private:
        py::ssize_t m_rows;
        py::ssize_t m_cols;
        float *m_data;
    };
    py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
        .def(py::init<py::ssize_t, py::ssize_t>())
        /// Construct from a buffer
        .def(py::init([](const py::buffer &b) {
            py::buffer_info info = b.request();
            if (info.format != py::format_descriptor<float>::format() || info.ndim != 2) {
                throw std::runtime_error("Incompatible buffer format!");
            }

            auto *v = new Matrix(info.shape[0], info.shape[1]);
            memcpy(v->data(), info.ptr, sizeof(float) * (size_t) (v->rows() * v->cols()));
            return v;
        }))

        .def("rows", &Matrix::rows)
        .def("cols", &Matrix::cols)

        /// Bare bones interface
        .def("__getitem__",
             [](const Matrix &m, std::pair<py::ssize_t, py::ssize_t> i) {
                 if (i.first >= m.rows() || i.second >= m.cols()) {
                     throw py::index_error();
                 }
                 return m(i.first, i.second);
             })
        .def("__setitem__",
             [](Matrix &m, std::pair<py::ssize_t, py::ssize_t> i, float v) {
                 if (i.first >= m.rows() || i.second >= m.cols()) {
                     throw py::index_error();
                 }
                 m(i.first, i.second) = v;
             })
        /// Provide buffer access
        .def_buffer([](Matrix &m) -> py::buffer_info {
            return py::buffer_info(
                m.data(),                          /* Pointer to buffer */
                {m.rows(), m.cols()},              /* Buffer dimensions */
                {sizeof(float) * size_t(m.cols()), /* Strides (in bytes) for each index */
                 sizeof(float)});
        });

    // A matrix that uses Fortran storage order.
    class FortranMatrix : public Matrix {
    public:
        FortranMatrix(py::ssize_t rows, py::ssize_t cols) : Matrix(cols, rows) {
            print_created(this,
                          std::to_string(rows) + "x" + std::to_string(cols) + " Fortran matrix");
        }

        float operator()(py::ssize_t i, py::ssize_t j) const { return Matrix::operator()(j, i); }

        float &operator()(py::ssize_t i, py::ssize_t j) { return Matrix::operator()(j, i); }

        using Matrix::data;

        py::ssize_t rows() const { return Matrix::cols(); }
        py::ssize_t cols() const { return Matrix::rows(); }
    };
    py::class_<FortranMatrix, Matrix>(m, "FortranMatrix", py::buffer_protocol())
        .def(py::init<py::ssize_t, py::ssize_t>())

        .def("rows", &FortranMatrix::rows)
        .def("cols", &FortranMatrix::cols)

        /// Bare bones interface
        .def("__getitem__",
             [](const FortranMatrix &m, std::pair<py::ssize_t, py::ssize_t> i) {
                 if (i.first >= m.rows() || i.second >= m.cols()) {
                     throw py::index_error();
                 }
                 return m(i.first, i.second);
             })
        .def("__setitem__",
             [](FortranMatrix &m, std::pair<py::ssize_t, py::ssize_t> i, float v) {
                 if (i.first >= m.rows() || i.second >= m.cols()) {
                     throw py::index_error();
                 }
                 m(i.first, i.second) = v;
             })
        /// Provide buffer access
        .def_buffer([](FortranMatrix &m) -> py::buffer_info {
            return py::buffer_info(m.data(),             /* Pointer to buffer */
                                   {m.rows(), m.cols()}, /* Buffer dimensions */
                                   /* Strides (in bytes) for each index */
                                   {sizeof(float), sizeof(float) * size_t(m.rows())});
        });

    // A matrix that uses a discontiguous underlying memory block.
    class DiscontiguousMatrix : public Matrix {
    public:
        DiscontiguousMatrix(py::ssize_t rows,
                            py::ssize_t cols,
                            py::ssize_t row_factor,
                            py::ssize_t col_factor)
            : Matrix(rows * row_factor, cols * col_factor), m_row_factor(row_factor),
              m_col_factor(col_factor) {
            print_created(this,
                          std::to_string(rows) + "(*" + std::to_string(row_factor) + ")x"
                              + std::to_string(cols) + "(*" + std::to_string(col_factor)
                              + ") matrix");
        }
        DiscontiguousMatrix(const DiscontiguousMatrix &) = delete;
        ~DiscontiguousMatrix() {
            print_destroyed(this,
                            std::to_string(rows() / m_row_factor) + "(*"
                                + std::to_string(m_row_factor) + ")x"
                                + std::to_string(cols() / m_col_factor) + "(*"
                                + std::to_string(m_col_factor) + ") matrix");
        }

        float operator()(py::ssize_t i, py::ssize_t j) const {
            return Matrix::operator()(i *m_row_factor, j *m_col_factor);
        }

        float &operator()(py::ssize_t i, py::ssize_t j) {
            return Matrix::operator()(i *m_row_factor, j *m_col_factor);
        }

        using Matrix::data;

        py::ssize_t rows() const { return Matrix::rows() / m_row_factor; }
        py::ssize_t cols() const { return Matrix::cols() / m_col_factor; }
        py::ssize_t row_factor() const { return m_row_factor; }
        py::ssize_t col_factor() const { return m_col_factor; }

    private:
        py::ssize_t m_row_factor;
        py::ssize_t m_col_factor;
    };
    py::class_<DiscontiguousMatrix, Matrix>(m, "DiscontiguousMatrix", py::buffer_protocol())
        .def(py::init<py::ssize_t, py::ssize_t, py::ssize_t, py::ssize_t>())

        .def("rows", &DiscontiguousMatrix::rows)
        .def("cols", &DiscontiguousMatrix::cols)

        /// Bare bones interface
        .def("__getitem__",
             [](const DiscontiguousMatrix &m, std::pair<py::ssize_t, py::ssize_t> i) {
                 if (i.first >= m.rows() || i.second >= m.cols()) {
                     throw py::index_error();
                 }
                 return m(i.first, i.second);
             })
        .def("__setitem__",
             [](DiscontiguousMatrix &m, std::pair<py::ssize_t, py::ssize_t> i, float v) {
                 if (i.first >= m.rows() || i.second >= m.cols()) {
                     throw py::index_error();
                 }
                 m(i.first, i.second) = v;
             })
        /// Provide buffer access
        .def_buffer([](DiscontiguousMatrix &m) -> py::buffer_info {
            return py::buffer_info(m.data(),             /* Pointer to buffer */
                                   {m.rows(), m.cols()}, /* Buffer dimensions */
                                   /* Strides (in bytes) for each index */
                                   {size_t(m.col_factor()) * sizeof(float) * size_t(m.cols())
                                        * size_t(m.row_factor()),
                                    size_t(m.col_factor()) * sizeof(float)});
        });

    class BrokenMatrix : public Matrix {
    public:
        BrokenMatrix(py::ssize_t rows, py::ssize_t cols) : Matrix(rows, cols) {}
        void throw_runtime_error() { throw std::runtime_error("See PR #5324 for context."); }
    };
    py::class_<BrokenMatrix>(m, "BrokenMatrix", py::buffer_protocol())
        .def(py::init<py::ssize_t, py::ssize_t>())
        .def_buffer([](BrokenMatrix &m) {
            m.throw_runtime_error();
            return py::buffer_info();
        });

    // test_inherited_protocol
    class SquareMatrix : public Matrix {
    public:
        explicit SquareMatrix(py::ssize_t n) : Matrix(n, n) {}
    };
    // Derived classes inherit the buffer protocol and the buffer access function
    py::class_<SquareMatrix, Matrix>(m, "SquareMatrix").def(py::init<py::ssize_t>());

    // test_pointer_to_member_fn
    // Tests that passing a pointer to member to the base class works in
    // the derived class.
    struct Buffer {
        int32_t value = 0;

        py::buffer_info get_buffer_info() {
            return py::buffer_info(
                &value, sizeof(value), py::format_descriptor<int32_t>::format(), 1);
        }
    };
    py::class_<Buffer>(m, "Buffer", py::buffer_protocol())
        .def(py::init<>())
        .def_readwrite("value", &Buffer::value)
        .def_buffer(&Buffer::get_buffer_info);

    class ConstBuffer {
        std::unique_ptr<int32_t> value;

    public:
        int32_t get_value() const { return *value; }
        void set_value(int32_t v) { *value = v; }

        py::buffer_info get_buffer_info() const {
            return py::buffer_info(
                value.get(), sizeof(*value), py::format_descriptor<int32_t>::format(), 1);
        }

        ConstBuffer() : value(new int32_t{0}) {}
    };
    py::class_<ConstBuffer>(m, "ConstBuffer", py::buffer_protocol())
        .def(py::init<>())
        .def_property("value", &ConstBuffer::get_value, &ConstBuffer::set_value)
        .def_buffer(&ConstBuffer::get_buffer_info);

    struct DerivedBuffer : public Buffer {};
    py::class_<DerivedBuffer>(m, "DerivedBuffer", py::buffer_protocol())
        .def(py::init<>())
        .def_readwrite("value", (int32_t DerivedBuffer::*) &DerivedBuffer::value)
        .def_buffer(&DerivedBuffer::get_buffer_info);

    struct BufferReadOnly {
        const uint8_t value = 0;
        explicit BufferReadOnly(uint8_t value) : value(value) {}

        py::buffer_info get_buffer_info() { return py::buffer_info(&value, 1); }
    };
    py::class_<BufferReadOnly>(m, "BufferReadOnly", py::buffer_protocol())
        .def(py::init<uint8_t>())
        .def_buffer(&BufferReadOnly::get_buffer_info);

    struct BufferReadOnlySelect {
        uint8_t value = 0;
        bool readonly = false;

        py::buffer_info get_buffer_info() { return py::buffer_info(&value, 1, readonly); }
    };
    py::class_<BufferReadOnlySelect>(m, "BufferReadOnlySelect", py::buffer_protocol())
        .def(py::init<>())
        .def_readwrite("value", &BufferReadOnlySelect::value)
        .def_readwrite("readonly", &BufferReadOnlySelect::readonly)
        .def_buffer(&BufferReadOnlySelect::get_buffer_info);

    // Expose buffer_info for testing.
    py::class_<py::buffer_info>(m, "buffer_info")
        .def(py::init<>())
        .def_readonly("itemsize", &py::buffer_info::itemsize)
        .def_readonly("size", &py::buffer_info::size)
        .def_readonly("format", &py::buffer_info::format)
        .def_readonly("ndim", &py::buffer_info::ndim)
        .def_readonly("shape", &py::buffer_info::shape)
        .def_readonly("strides", &py::buffer_info::strides)
        .def_readonly("readonly", &py::buffer_info::readonly)
        .def("__repr__", [](py::handle self) {
            return py::str("itemsize={0.itemsize!r}, size={0.size!r}, format={0.format!r}, "
                           "ndim={0.ndim!r}, shape={0.shape!r}, strides={0.strides!r}, "
                           "readonly={0.readonly!r}")
                .format(self);
        });

    m.def("get_buffer_info", [](const py::buffer &buffer) { return buffer.request(); });

    // Expose Py_buffer for testing.
    m.attr("PyBUF_FORMAT") = PyBUF_FORMAT;
    m.attr("PyBUF_SIMPLE") = PyBUF_SIMPLE;
    m.attr("PyBUF_ND") = PyBUF_ND;
    m.attr("PyBUF_STRIDES") = PyBUF_STRIDES;
    m.attr("PyBUF_INDIRECT") = PyBUF_INDIRECT;
    m.attr("PyBUF_C_CONTIGUOUS") = PyBUF_C_CONTIGUOUS;
    m.attr("PyBUF_F_CONTIGUOUS") = PyBUF_F_CONTIGUOUS;
    m.attr("PyBUF_ANY_CONTIGUOUS") = PyBUF_ANY_CONTIGUOUS;

    m.def("get_py_buffer", [](const py::object &object, int flags) {
        Py_buffer buffer;
        memset(&buffer, 0, sizeof(Py_buffer));
        if (PyObject_GetBuffer(object.ptr(), &buffer, flags) == -1) {
            throw py::error_already_set();
        }

        auto SimpleNamespace = py::module_::import("types").attr("SimpleNamespace");
        py::object result = SimpleNamespace("len"_a = buffer.len,
                                            "readonly"_a = buffer.readonly,
                                            "itemsize"_a = buffer.itemsize,
                                            "format"_a = buffer.format,
                                            "ndim"_a = buffer.ndim,
                                            "shape"_a = py::none(),
                                            "strides"_a = py::none(),
                                            "suboffsets"_a = py::none());
        if (buffer.shape != nullptr) {
            py::list l;
            for (auto i = 0; i < buffer.ndim; i++) {
                l.append(buffer.shape[i]);
            }
            py::setattr(result, "shape", l);
        }
        if (buffer.strides != nullptr) {
            py::list l;
            for (auto i = 0; i < buffer.ndim; i++) {
                l.append(buffer.strides[i]);
            }
            py::setattr(result, "strides", l);
        }
        if (buffer.suboffsets != nullptr) {
            py::list l;
            for (auto i = 0; i < buffer.ndim; i++) {
                l.append(buffer.suboffsets[i]);
            }
            py::setattr(result, "suboffsets", l);
        }

        PyBuffer_Release(&buffer);
        return result;
    });
}
