/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#include <pybind11/embed.h> // everything needed for embedding

#include <fstream>
#include <string>
namespace py = pybind11;
using namespace py::literals;

int main() {
  py::scoped_interpreter guard{}; // start the interpreter and keep it alive

  printf(
      "++++++++++PLEASE MAKE SURE YOU ARE IN THE PYBIND_SAMPLE DIRECTORY WHEN "
      "RUNNING THE BINARY+++++++++\n");
  printf("This is so the program correctly finds the Python files in the "
         "pybind_sample directory\n\n");

  printf("We can read a Python file into a string and execute its entirety\n");
  std::ifstream ifs("print_sample.py", std::ifstream::in);
  std::string str = "";
  char c = ifs.get();
  while (ifs.good()) {
    str += c;
    c = ifs.get();
  }
  py::exec(str);
  ifs.close();

  printf("\nWe can call a Python module from a file\n");
  py::object sdk_validator = py::module_::import("validator_example");
  py::object validate = sdk_validator.attr("validate");
  py::object res = validate("some_string");

  if (res == py::bool_(true))
    printf("validate returned true\n");
  else
    printf("validate returned false\n");

  printf("\nWe can also mix direct execution and the C++ library\n");
  auto txn =
      py::dict("id"_a = "918544363", "asset"_a = py::dict("id"_a = "1111"));
  auto locals = py::dict("name"_a = "World", "number"_a = 42, "txn"_a = txn);
  py::exec(R"(
    def validate(transaction):
      print(f'Validating {transaction}')

      if (not transaction) or type(transaction) is not dict:
        return False
      if "id" not in transaction:
        return False
      if "asset" not in transaction:
        return False
      if "id" not in transaction["asset"]:
        return False
      if transaction["id"] == None or transaction["asset"] == None:
        return False
      return True
    is_valid = validate(txn)
    print(f"validate returned {is_valid}")
  )",
           py::globals(), locals);

  auto is_valid = locals["is_valid"].cast<bool>();

  if (is_valid)
    printf("Valid\n");
}
