#include <boost/asio.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/stable_vector.hpp>

#include "crow/app.h"
#include "crow/ci_map.h"
#include "crow/common.h"
#include "crow/dumb_timer_queue.h"
#include "crow/http_connection.h"
#include "crow/http_parser_merged.h"
#include "crow/http_request.h"
#include "crow/http_response.h"
#include "crow/http_server.h"
#include "crow/logging.h"
#include "crow/middleware.h"
#include "crow/middleware_context.h"
#include "crow/mustache.h"
#include "crow/parser.h"
#include "crow/query_string.h"
#include "crow/routing.h"
#include "crow/settings.h"
#include "crow/socket_adaptors.h"
#include "crow/utility.h"
#include "crow/websocket.h"

#include "redfish_v1.hpp"
#include "security_headers_middleware.hpp"
#include "ssl_key_handler.hpp"
#include "token_authorization_middleware.hpp"
#include "web_kvm.hpp"
#include "webassets.hpp"

#include "nlohmann/json.hpp"

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

#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_set>

static std::shared_ptr<dbus::connection> system_bus;
static std::vector<dbus::match> dbus_matches;
static std::shared_ptr<dbus::filter> sensor_filter;

struct DbusWebsocketSession {
  std::vector<dbus::match> matches;
  std::vector<dbus::filter> filters;
};

static boost::container::flat_map<crow::websocket::connection*,
                                  DbusWebsocketSession>
    sessions;

void on_property_update(dbus::filter& filter, boost::system::error_code ec,
                        dbus::message s) {
  std::string object_name;
  std::vector<std::pair<std::string, dbus::dbus_variant>> values;
  s.unpack(object_name).unpack(values);
  nlohmann::json j;
  for (auto& value : values) {
    boost::apply_visitor([&](auto val) { j[s.get_path()] = val; },
                         value.second);
  }
  auto data_to_send = j.dump();

  for (auto& session : sessions) {
    session.first->send_text(data_to_send);
  }
  filter.async_dispatch([&](boost::system::error_code ec, dbus::message s) {
    on_property_update(filter, ec, s);;
  });
};

int main(int argc, char** argv) {
  // Build an io_service (there should only be 1)
  auto io = std::make_shared<boost::asio::io_service>();

  bool enable_ssl = true;
  std::string ssl_pem_file("server.pem");

  if (enable_ssl) {
    ensuressl::ensure_openssl_key_present_and_valid(ssl_pem_file);
  }

  crow::App<
      crow::TokenAuthorizationMiddleware, crow::SecurityHeadersMiddleware>
      app(io);

  crow::webassets::request_routes(app);
  crow::kvm::request_routes(app);
  crow::redfish::request_routes(app);

  crow::logger::setLogLevel(crow::LogLevel::INFO);

  CROW_ROUTE(app, "/dbus_monitor")
      .websocket()
      .onopen([&](crow::websocket::connection& conn) {
        sessions[&conn] = DbusWebsocketSession();

        sessions[&conn].matches.emplace_back(
            system_bus,
            "type='signal',path_namespace='/xyz/openbmc_project/sensors'");

        sessions[&conn].filters.emplace_back(system_bus, [](dbus::message m) {
          auto member = m.get_member();
          return member == "PropertiesChanged";
        });
        auto& this_filter = sessions[&conn].filters.back();
        this_filter.async_dispatch(
            [&](boost::system::error_code ec, dbus::message s) {
              on_property_update(this_filter, ec, s);;
            });

      })
      .onclose(
          [&](crow::websocket::connection& conn, const std::string& reason) {
            sessions.erase(&conn);
          })
      .onmessage([&](crow::websocket::connection& conn, const std::string& data,
                     bool is_binary) {
        CROW_LOG_ERROR << "Got unexpected message from client on sensorws";
      });

  CROW_ROUTE(app, "/intel/firmwareupload")
      .methods("POST"_method)([](const crow::request& req) {
        auto filepath = "/tmp/fw_update_image";
        std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
                                        std::ofstream::trunc);
        out << req.body;
        out.close();

        nlohmann::json j;
        j["status"] = "Upload Successfull";

        dbus::endpoint fw_update_endpoint(
            "xyz.openbmc_project.fwupdate1.server",
            "/xyz/openbmc_project/fwupdate1", "xyz.openbmc_project.fwupdate1");

        auto m = dbus::message::new_call(fw_update_endpoint, "start");

        m.pack(std::string("file://") + filepath);
        system_bus->send(m);

        return j;
      });

  crow::logger::setLogLevel(crow::LogLevel::DEBUG);
  auto test = app.get_routes();
  app.debug_print();
  std::cout << "Building SSL context\n";

  int port = 18080;

  std::cout << "Starting webserver on port " << port << "\n";
  app.port(port);
  if (enable_ssl) {
    std::cout << "SSL Enabled\n";
    auto ssl_context = ensuressl::get_ssl_context(ssl_pem_file);
    app.ssl(std::move(ssl_context));
  }
  // app.concurrency(4);

  // Start dbus connection
  system_bus = std::make_shared<dbus::connection>(*io, dbus::bus::system);

  app.run();
}
