/*
    example/example2.cpp2 -- singleton design pattern, static functions and
    variables, passing and interacting with Python types

    Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.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 "example.h"
#include <pybind11/stl.h>

class Example2 {
public:
    static Example2 *new_instance() {
        return new Example2();
    }
    ~Example2() {
        std::cout << "Destructing Example2" << std::endl;
    }

    /* Create and return a Python dictionary */
    py::dict get_dict() {
        py::dict dict;
        dict[py::str("key")] = py::str("value");
        return dict;
    }

    /* Create and return a C++ dictionary */
    std::map<std::string, std::string> get_dict_2() {
        std::map<std::string, std::string> result;
        result["key"] = "value";
        return result;
    }

    /* Create, manipulate, and return a Python list */
    py::list get_list() {
        py::list list;
        list.append(py::str("value"));
        cout << "Entry at positon 0: " << py::object(list[0]) << endl;
        list[0] = py::str("overwritten");
        return list;
    }

    /* C++ STL data types are automatically casted */
    std::vector<std::string> get_list_2() {
        std::vector<std::string> list;
        list.push_back("value");
        return list;
    }

    /* Easily iterate over a dictionary using a C++11 range-based for loop */
    void print_dict(py::dict dict) {
        for (auto item : dict)
            std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
    }

    /* STL data types are automatically casted from Python */
    void print_dict_2(const std::map<std::string, std::string> &dict) {
        for (auto item : dict)
            std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
    }

    /* Easily iterate over a list using a C++11 range-based for loop */
    void print_list(py::list list) {
        int index = 0;
        for (auto item : list)
            std::cout << "list item " << index++ << ": " << item << std::endl;
    }

    /* STL data types are automatically casted from Python */
    void print_list_2(std::vector<std::string> &list) {
        int index = 0;
        for (auto item : list)
            std::cout << "list item " << index++ << ": " << item << std::endl;
    }

    /* pybind automatically translates between C++11 and Python tuples */
    std::pair<std::string, bool> pair_passthrough(std::pair<bool, std::string> input) {
        return std::make_pair(input.second, input.first);
    }

    /* pybind automatically translates between C++11 and Python tuples */
    std::tuple<int, std::string, bool> tuple_passthrough(std::tuple<bool, std::string, int> input) {
        return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input));
    }

    void throw_exception() {
        throw std::runtime_error("This exception was intentionally thrown.");
    }

    static int value;
    static const int value2;
};

int Example2::value = 0;
const int Example2::value2 = 5;

void init_ex2(py::module &m) {
    /* No constructor is explicitly defined below. An exception is raised when
       trying to construct it directly from Python */
    py::class_<Example2>(m, "Example2", "Example 2 documentation")
        .def("get_dict", &Example2::get_dict, "Return a Python dictionary")
        .def("get_dict_2", &Example2::get_dict_2, "Return a C++ dictionary")
        .def("get_list", &Example2::get_list, "Return a Python list")
        .def("get_list_2", &Example2::get_list_2, "Return a C++ list")
        .def("print_dict", &Example2::print_dict, "Print entries of a Python dictionary")
        .def("print_dict_2", &Example2::print_dict_2, "Print entries of a C++ dictionary")
        .def("print_list", &Example2::print_list, "Print entries of a Python list")
        .def("print_list_2", &Example2::print_list_2, "Print entries of a C++ list")
        .def("pair_passthrough", &Example2::pair_passthrough, "Return a pair in reversed order")
        .def("tuple_passthrough", &Example2::tuple_passthrough, "Return a triple in reversed order")
        .def("throw_exception", &Example2::throw_exception, "Throw an exception")
        .def_static("new_instance", &Example2::new_instance, "Return an instance")
        .def_readwrite_static("value", &Example2::value, "Static value member")
        .def_readonly_static("value2", &Example2::value2, "Static value member (readonly)");
}
