#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_IMAGE_UPLOAD_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_IMAGE_UPLOAD_H_

#include <algorithm>
#include <chrono>      // NOLINT
#include <fstream>     // NOLINT
#include <functional>  // NOLINT
#include <memory>      // NOLINT
#include <string>

#include "boost/uuid/uuid.hpp"  // NOLINT
#include "boost/uuid/uuid_generators.hpp"  // NOLINT
#include "boost/uuid/uuid_io.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "managed_store.hpp"
#include "sdbusplus/bus/match.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"  // NOLINT
#endif

namespace crow {
namespace image_upload {

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static std::unique_ptr<sdbusplus::bus::match_t> fwUpdateMatcher;

inline void uploadImageHandler(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  // Only allow one FW update at a time
  if (fwUpdateMatcher != nullptr) {
    asyncResp->res.addHeader("Retry-After", "30");
    asyncResp->res.result(boost::beast::http::status::service_unavailable);
    return;
  }
  // Make this const static so it survives outside this method
  static boost::asio::steady_timer timeout(*req.ioService,
                                           std::chrono::seconds(5));

  timeout.expires_after(std::chrono::seconds(15));

  auto timeoutHandler = [asyncResp](const boost::system::error_code& ec) {
    fwUpdateMatcher = nullptr;
    if (ec == boost::asio::error::operation_aborted) {
      // expected, we were canceled before the timer completed.
      return;
    }
    BMCWEB_LOG_ERROR << "Timed out waiting for Version interface";

    if (ec) {
      BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
      return;
    }

    asyncResp->res.result(boost::beast::http::status::bad_request);
    asyncResp->res.jsonValue["data"]["description"] =
        "Version already exists or failed to be extracted";
    asyncResp->res.jsonValue["message"] = "400 Bad Request";
    asyncResp->res.jsonValue["status"] = "error";
  };

  std::function<void(sdbusplus::message_t&)> callback =
      [asyncResp](sdbusplus::message_t& m) {
        BMCWEB_LOG_DEBUG << "Match fired";

        sdbusplus::message::object_path path;
        dbus::utility::DBusInteracesMap interfaces;
        m.read(path, interfaces);

        if (std::find_if(
                interfaces.begin(), interfaces.end(), [](const auto& i) {
                  return i.first == "xyz.openbmc_project.Software.Version";
                }) != interfaces.end()) {
          timeout.cancel();
          std::string leaf = path.filename();
          if (leaf.empty()) {
            leaf = path.str;
          }

          asyncResp->res.jsonValue["data"] = leaf;
          asyncResp->res.jsonValue["message"] = "200 OK";
          asyncResp->res.jsonValue["status"] = "ok";
          BMCWEB_LOG_DEBUG << "ending response";
          fwUpdateMatcher = nullptr;
        }
      };
  fwUpdateMatcher = std::make_unique<sdbusplus::bus::match_t>(
      *(managedStore::GetManagedObjectStore()
            ->GetDeprecatedThreadUnsafeSystemBus()),
      "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
      "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
      callback);

  std::string filepath(
      "/tmp/images/" +
      boost::uuids::to_string(boost::uuids::random_generator()()));
  BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
  std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
                                  std::ofstream::trunc);
  out << req.body();
  out.close();
  timeout.async_wait(timeoutHandler);
}

inline void requestRoutes(App& app) {
  BMCWEB_ROUTE(app, "/upload/image/<str>")
      .privileges({{"ConfigureComponents", "ConfigureManager"}})
      .methods(boost::beast::http::verb::post, boost::beast::http::verb::put)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
             const std::string&) { uploadImageHandler(req, asyncResp); });

  BMCWEB_ROUTE(app, "/upload/image")
      .privileges({{"ConfigureComponents", "ConfigureManager"}})
      .methods(boost::beast::http::verb::post, boost::beast::http::verb::put)(
          [](const crow::Request& req,
             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
            uploadImageHandler(req, asyncResp);
          });
}
}  // namespace image_upload
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_INCLUDE_IMAGE_UPLOAD_H_
