#include <crow/app.h>

#include <tinyxml2.h>
#include <dbus/connection.hpp>
#include <dbus/endpoint.hpp>
#include <dbus/filter.hpp>
#include <dbus/match.hpp>
#include <dbus/message.hpp>
#include <dbus_singleton.hpp>

namespace crow {
namespace openbmc_mapper {

// TODO(ed) having these as scope globals, and as simple as they are limits the
// ability to queue multiple async operations at once.  Being able to register
// "done" callbacks to a queue here that also had a count attached would allow
// multiple requests to be running at once
std::atomic<std::size_t> outstanding_async_calls(0);
nlohmann::json object_paths;
bool property_matched=false;
void introspect_objects(crow::response &res, std::string process_name,
                        std::string path) {
  dbus::endpoint introspect_endpoint(
      process_name, path, "org.freedesktop.DBus.Introspectable", "Introspect");
  outstanding_async_calls++;
  crow::connections::system_bus->async_method_call(
      [&, process_name{std::move(process_name)}, object_path{std::move(path)} ](
          const boost::system::error_code ec,
          const std::string &introspect_xml) {
        outstanding_async_calls--;
        if (ec) {
          std::cerr << "Introspect call failed with error: " << ec.message()
                    << " on process: " << process_name
                    << " path: " << object_path << "\n";

        } else {
          object_paths.push_back({{"path", object_path}});

          tinyxml2::XMLDocument doc;

          doc.Parse(introspect_xml.c_str());
          tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
          if (pRoot == nullptr) {
            std::cerr << "XML document failed to parse " << process_name << " "
                      << path << "\n";

          } else {
            tinyxml2::XMLElement *node = pRoot->FirstChildElement("node");
            while (node != nullptr) {
              std::string child_path = node->Attribute("name");
              std::string newpath;
              if (object_path != "/") {
                newpath += object_path;
              }
              newpath += "/" + child_path;
              // intropect the subobjects as well
              introspect_objects(res, process_name, newpath);

              node = node->NextSiblingElement("node");
            }
          }
        }
        // if we're the last outstanding caller, finish the request
        if (outstanding_async_calls == 0) {
          nlohmann::json j{{"status", "ok"},
                           {"bus_name", process_name},
                           {"objects", object_paths}};

          res.write(j.dump());
          object_paths.clear();
          res.end();
        }
      },
      introspect_endpoint);
}

template <typename... Middlewares>
void request_routes(Crow<Middlewares...> &app) {
  CROW_ROUTE(app, "/bus/").methods("GET"_method)([](const crow::request &req) {
    return nlohmann::json{{"busses", {{{"name", "system"}}}}, {"status", "ok"}};

  });

  CROW_ROUTE(app, "/bus/system/")
      .methods("GET"_method)([](const crow::request &req, crow::response &res) {
        crow::connections::system_bus->async_method_call(
            [&](const boost::system::error_code ec,
                std::vector<std::string> &names) {
              std::sort(names.begin(), names.end());
              if (ec) {
                res.code = 500;
              } else {
                nlohmann::json j{{"status", "ok"}};
                auto &objects_sub = j["objects"];
                for (auto &name : names) {
                  objects_sub.push_back({{"name", name}});
                }

                res.write(j.dump());
              }

              res.end();

            },
            {"org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames"});

      });

  CROW_ROUTE(app, "/list/")
      .methods("GET"_method)([](const crow::request &req, crow::response &res) {
        crow::connections::system_bus->async_method_call(
            [&](const boost::system::error_code ec,
                const std::vector<std::string> &object_paths) {

              if (ec) {
                res.code = 500;
              } else {
                nlohmann::json j{{"status", "ok"},
                                 {"message", "200 OK"},
                                 {"data", object_paths}};
                res.body = j.dump();
              }
              res.end();
            },
            {"xyz.openbmc_project.ObjectMapper",
             "/xyz/openbmc_project/object_mapper",
             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"},
            "", static_cast<int32_t>(99), std::array<std::string, 0>());
      });

 CROW_ROUTE(app, "/xyz/<path>")
      .methods("GET"_method,
               "PUT"_method)([](const crow::request &req, crow::response &res,
                                const std::string &path) {
        if (outstanding_async_calls != 0) {
          res.code = 500;
          res.body = "request in progress";
          res.end();
          return;
        }
        using GetObjectType =
            std::vector<std::pair<std::string, std::vector<std::string>>>;
        std::string object_path;
        std::string dest_property;
        std::string property_set_value;
        size_t attr_position = path.find("/attr/");
        if (attr_position == path.npos)
          object_path = "/xyz/" + path;
        else {
          object_path = "/xyz/" + path.substr(0, attr_position);
          dest_property =
              path.substr((attr_position + strlen("/attr/")), path.length());
          auto request_dbus_data =
              nlohmann::json::parse(req.body, nullptr, false);
          if (request_dbus_data.is_discarded()) {
            res.code = 400;
            res.end();
            return;
          }

          auto property_value_it = request_dbus_data.find("data");
          if (property_value_it == request_dbus_data.end()) {
            res.code = 400;
            res.end();
            return;
          }

          property_set_value = property_value_it->get<const std::string>();
          if (property_set_value.empty()) {
            res.code = 400;
            res.end();
            return;
          }
        }

        crow::connections::system_bus->async_method_call(
            // object_path intentially captured by value
            [
                  &, object_path, dest_property{std::move(dest_property)},
                  property_set_value{std::move(property_set_value)}
            ](const boost::system::error_code ec,
              const GetObjectType &object_names) {
              if (ec) {
                res.code = 500;
                res.end();
                return;
              }
              if (object_names.size() != 1) {
                res.code = 404;
                res.end();
                return;
              }
              if (req.method == "GET"_method) {
                for (auto &interface : object_names[0].second) {
                  outstanding_async_calls++;
                  crow::connections::system_bus->async_method_call(
                      [&](const boost::system::error_code ec,
                          const std::vector<std::pair<
                              std::string, dbus::dbus_variant>> &properties) {
                        outstanding_async_calls--;
                        if (ec) {
                          std::cerr << "Bad dbus request error: " << ec;
                        } else {
                          for (auto &property : properties) {
                            boost::apply_visitor(
                                [&](auto val) {
                                  object_paths[property.first] = val;
                                },
                                property.second);
                          }
                        }
                        if (outstanding_async_calls == 0) {
                          nlohmann::json j{{"status", "ok"},
                                           {"message", "200 OK"},
                                           {"data", object_paths}};
                          res.body = j.dump();
                          res.end();
                          object_paths.clear();
                        }
                      },
                      {object_names[0].first, object_path,
                       "org.freedesktop.DBus.Properties", "GetAll"},
                      interface);
                }
              } else if (req.method == "PUT"_method) {
                for (auto &interface : object_names[0].second) {
                  outstanding_async_calls++;
                  crow::connections::system_bus->async_method_call(
                      [
                            &, interface{std::move(interface)},
                            object_names{std::move(object_names)},
                            object_path{std::move(object_path)},
                            dest_property{std::move(dest_property)},
                            property_set_value{std::move(property_set_value)}
                      ](const boost::system::error_code ec,
                        const std::vector<std::pair<
                            std::string, dbus::dbus_variant>> &properties) {
                        outstanding_async_calls--;
                        if (ec) {
                          std::cerr << "Bad dbus request error: " << ec;
                        } else {
                          for (auto &property : properties) {
                            // search all the properties in the interfaces
                            if (dest_property.compare(property.first) == 0) {
                              // find the matched property in the interface
                              property_matched = true;
                              dbus::dbus_variant property_value(
                                  property_set_value);  // create the dbus
                                                        // variant for dbus call
                              crow::connections::system_bus->async_method_call(
                                  [&](const boost::system::error_code ec) {
                                    // use the method "Set" to set the property
                                    // value
                                    if (ec) {
                                      std::cerr << "Bad dbus request error: "
                                                << ec;
                                      res.code = 500;
                                      res.end();
                                    } else {
                                      // find the matched property and send the
                                      // response
                                      res.json_value = {{"status", "ok"},
                                                        {"message", "200 OK"},
                                                        {"data", NULL}};
                                      res.end();
                                      return;
                                    }
                                  },
                                  {object_names[0].first, object_path,
                                   "org.freedesktop.DBus.Properties", "Set"},
                                  interface, dest_property, property_value);
                            }
                          }
                          if (outstanding_async_calls == 0) {
                            // all search has been finished
                            if (property_matched == false) {
                              nlohmann::json j{{"status", "error"},
                                               {"message", "403 Forbidden"},
                                               {"data",
                                                {{"message",
                                                  "The specified property "
                                                  "cannot be created: " +
                                                      dest_property}}}};
                              res.json_value = j;
                              res.end();
                              return;
                            } else
                              property_matched = false;
                          }
                        }
                      },
                      {object_names[0].first, object_path,
                       "org.freedesktop.DBus.Properties", "GetAll"},
                      interface);
                }
              }
            },
            {"xyz.openbmc_project.ObjectMapper",
             "/xyz/openbmc_project/object_mapper",
             "xyz.openbmc_project.ObjectMapper", "GetObject"},
            object_path, std::array<std::string, 0>());
      });

  CROW_ROUTE(app, "/bus/system/<str>/")
      .methods("GET"_method)([](const crow::request &req, crow::response &res,
                                const std::string &connection) {
        if (outstanding_async_calls != 0) {
          res.code = 500;
          res.body = "request in progress";
          res.end();
          return;
        }
        introspect_objects(res, connection, "/");
      });

  CROW_ROUTE(app, "/bus/system/<str>/<path>")
      .methods("GET"_method)([](const crow::request &req, crow::response &res,
                                const std::string &process_name,
                                const std::string &requested_path) {

        std::vector<std::string> strs;
        boost::split(strs, requested_path, boost::is_any_of("/"));
        std::string object_path;
        std::string interface_name;
        std::string method_name;
        auto it = strs.begin();
        if (it == strs.end()) {
          object_path = "/";
        }
        while (it != strs.end()) {
          // Check if segment contains ".".  If it does, it must be an
          // interface
          if ((*it).find(".") != std::string::npos) {
            break;
            // THis check is neccesary as the trailing slash gets parsed as
            // part
            // of our <path> specifier above, which causes the normal trailing
            // backslash redirector to fail.
          } else if (!it->empty()) {
            object_path += "/" + *it;
          }
          it++;
        }
        if (it != strs.end()) {
          interface_name = *it;
          it++;

          // after interface, we might have a method name
          if (it != strs.end()) {
            method_name = *it;
            it++;
          }
        }
        if (it != strs.end()) {
          // if there is more levels past the method name, something went
          // wrong, throw an error
          res.code = 404;
          res.end();
          return;
        }
        dbus::endpoint introspect_endpoint(
            process_name, object_path, "org.freedesktop.DBus.Introspectable",
            "Introspect");
        if (interface_name.empty()) {
          crow::connections::system_bus->async_method_call(
              [
                    &, process_name{std::move(process_name)},
                    object_path{std::move(object_path)}
              ](const boost::system::error_code ec,
                const std::string &introspect_xml) {
                if (ec) {
                  std::cerr
                      << "Introspect call failed with error: " << ec.message()
                      << " on process: " << process_name
                      << " path: " << object_path << "\n";

                } else {
                  tinyxml2::XMLDocument doc;

                  doc.Parse(introspect_xml.c_str());
                  tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
                  if (pRoot == nullptr) {
                    std::cerr << "XML document failed to parse " << process_name
                              << " " << object_path << "\n";
                    res.write(nlohmann::json{{"status", "XML parse error"}});
                    res.code = 500;
                  } else {
                    nlohmann::json interfaces_array = nlohmann::json::array();
                    tinyxml2::XMLElement *interface =
                        pRoot->FirstChildElement("interface");

                    while (interface != nullptr) {
                      std::string iface_name = interface->Attribute("name");
                      interfaces_array.push_back({{"name", iface_name}});

                      interface = interface->NextSiblingElement("interface");
                    }
                    nlohmann::json j{{"status", "ok"},
                                     {"bus_name", process_name},
                                     {"interfaces", interfaces_array},
                                     {"object_path", object_path}};
                    res.write(j.dump());
                  }
                }
                res.end();
              },
              introspect_endpoint);
        } else {
          crow::connections::system_bus->async_method_call(
              [
                    &, process_name{std::move(process_name)},
                    interface_name{std::move(interface_name)},
                    object_path{std::move(object_path)}
              ](const boost::system::error_code ec,
                const std::string &introspect_xml) {
                if (ec) {
                  std::cerr
                      << "Introspect call failed with error: " << ec.message()
                      << " on process: " << process_name
                      << " path: " << object_path << "\n";

                } else {
                  tinyxml2::XMLDocument doc;

                  doc.Parse(introspect_xml.c_str());
                  tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
                  if (pRoot == nullptr) {
                    std::cerr << "XML document failed to parse " << process_name
                              << " " << object_path << "\n";
                    res.code = 500;

                  } else {
                    tinyxml2::XMLElement *node =
                        pRoot->FirstChildElement("node");

                    // if we know we're the only call, build the json directly
                    nlohmann::json methods_array = nlohmann::json::array();
                    nlohmann::json signals_array = nlohmann::json::array();
                    tinyxml2::XMLElement *interface =
                        pRoot->FirstChildElement("interface");

                    while (interface != nullptr) {
                      std::string iface_name = interface->Attribute("name");

                      if (iface_name == interface_name) {
                        tinyxml2::XMLElement *methods =
                            interface->FirstChildElement("method");
                        while (methods != nullptr) {
                          nlohmann::json args_array = nlohmann::json::array();
                          tinyxml2::XMLElement *arg =
                              methods->FirstChildElement("arg");
                          while (arg != nullptr) {
                            args_array.push_back(
                                {{"name", arg->Attribute("name")},
                                 {"type", arg->Attribute("type")},
                                 {"direction", arg->Attribute("direction")}});
                            arg = arg->NextSiblingElement("arg");
                          }
                          methods_array.push_back(
                              {{"name", methods->Attribute("name")},
                               {"uri",
                                "/bus/system/" + process_name + object_path +
                                    "/" + interface_name + "/" +
                                    methods->Attribute("name")},
                               {"args", args_array}});
                          methods = methods->NextSiblingElement("method");
                        }
                        tinyxml2::XMLElement *signals =
                            interface->FirstChildElement("signal");
                        while (signals != nullptr) {
                          nlohmann::json args_array = nlohmann::json::array();

                          tinyxml2::XMLElement *arg =
                              signals->FirstChildElement("arg");
                          while (arg != nullptr) {
                            std::string name = arg->Attribute("name");
                            std::string type = arg->Attribute("type");
                            args_array.push_back({
                                {"name", name}, {"type", type},
                            });
                            arg = arg->NextSiblingElement("arg");
                          }
                          signals_array.push_back(
                              {{"name", signals->Attribute("name")},
                               {"args", args_array}});
                          signals = signals->NextSiblingElement("signal");
                        }

                        nlohmann::json j{
                            {"status", "ok"},
                            {"bus_name", process_name},
                            {"interface", interface_name},
                            {"methods", methods_array},
                            {"object_path", object_path},
                            {"properties", nlohmann::json::object()},
                            {"signals", signals_array}};

                        res.write(j.dump());
                        break;
                      }

                      interface = interface->NextSiblingElement("interface");
                    }
                    if (interface == nullptr) {
                      // if we got to the end of the list and never found a
                      // match, throw 404
                      res.code = 404;
                    }
                  }
                }
                res.end();
              },
              introspect_endpoint);
        }

      });
}
}  // namespace openbmc_mapper
}  // namespace crow
