#include "midas.h"
#include "odbxx.h"
#include "tinyexpr.h"

#include <iostream>
#include <string>

double odb_query(std::span<const te_arg> args)
{
   if (args.size() != 1 || !std::holds_alternative<std::string_view>(args[0]))
      return te_parser::te_nan;

   const std::string path{ std::get<std::string_view>(args[0]) };
   if (!midas::odb::exists(path))
      return te_parser::te_nan;

   try {
      midas::odb value(path);
      return static_cast<double>(value);
   } catch (...) {
      return te_parser::te_nan;
   }
}

int main()
{
   if (cm_connect_experiment(nullptr, nullptr, "odb_tinyexpr", nullptr) != CM_SUCCESS) {
      std::cerr << "Cannot connect to the experiment.\n";
      return 1;
   }

   te_parser parser;
   parser.set_variables_and_functions({ { "odb_query", static_cast<te_arg_fun>(odb_query) } });

   const auto expression = R"(odb_query("/Runinfo/Run number") * 2)";
   const double result = parser.evaluate(expression);
   if (!parser.success()) {
      std::cerr << "Cannot evaluate: " << expression << '\n';
      cm_disconnect_experiment();
      return 1;
   }

   std::cout << expression << " = " << result << '\n';
   cm_disconnect_experiment();
   return 0;
}
