#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_

#include <systemd/sd-daemon.h>

#include <chrono>  // NOLINT
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <thread>  // NOLINT
#include <utility>

// NOLINTBEGIN
#include "absl/base/log_severity.h"
#include "absl/flags/declare.h"
#include "absl/types/optional.h"
#include "boost/asio/thread_pool.hpp"  // NOLINT
#include "g3/event_store.h"
#include "subscription.h"
#include "subscription_impl.h"
#include "subscription_store_impl.h"
#include "bmcweb_config.h"
#include "app.hpp"
#include "app_singleton.hpp"
#ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER
#include "exception_stack_tracer.hpp"
#endif
#include "logging.hpp"
#include "cors_preflight.hpp"
#include "persistent_data.hpp"
#include "request_stats.hpp"
#include "user_monitor.hpp"
#include "webassets.hpp"
#include "interface.hpp"
#include "redfish.hpp"
#include "health.hpp"
#include "tlbmc/credentials/credential_manager.h"
#include "tlbmc/credentials/credential_manager_impl.h"
#include "tlbmc/hal/system_registry.h"
#include "tlbmc/hal/system_registry_impl.h"
#include "tlbmc/redfish/app.h"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "subscription_backend_impl.hpp"

#ifdef BMCWEB_ENABLE_GRPC
#include "absl/flags/flag.h"
#include "absl/log/initialize.h"
#include "absl/log/log.h"
#include "server.h"

// NOLINTEND

// See absl/log/globals.h for detailed instructions
ABSL_DECLARE_FLAG(int, stderrthreshold);
ABSL_DECLARE_FLAG(int, minloglevel);
ABSL_DECLARE_FLAG(absl::optional<int>, httpport);
ABSL_DECLARE_FLAG(int, mtls_grpc_port);
ABSL_DECLARE_FLAG(int, insecure_grpc_port);

// BMCWEB_ENABLE_STATEFUL_BMCWEB:
ABSL_DECLARE_FLAG(absl::optional<bool>, stateful);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_pending_max);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tfixed_sec);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tgrace_sec);
ABSL_DECLARE_FLAG(absl::optional<int>, stateful_tlru_sec);
ABSL_DECLARE_FLAG(absl::optional<bool>, request_stats);
ABSL_DECLARE_FLAG(absl::optional<bool>, timetrace);
ABSL_DECLARE_FLAG(absl::optional<uint64_t>, timetrace_size_max);
ABSL_DECLARE_FLAG(absl::optional<bool>, stateful_logs);
ABSL_DECLARE_FLAG(bool, redfish_events);
ABSL_DECLARE_FLAG(bool, testing_events);
ABSL_DECLARE_FLAG(absl::optional<size_t>, redfish_event_store_size);
ABSL_DECLARE_FLAG(absl::optional<bool>, rde_ratelimit);
ABSL_DECLARE_FLAG(absl::optional<int>, rde_errors_max);
ABSL_DECLARE_FLAG(absl::optional<int>, rde_skips_max);
ABSL_DECLARE_FLAG(bool, multi_thread_get);
ABSL_DECLARE_FLAG(bool, exception_stack_tracer);
ABSL_DECLARE_FLAG(bool, enable_tlbmc);
ABSL_DECLARE_FLAG(bool, enable_tlbmc_trace);
ABSL_DECLARE_FLAG(bool, enable_tlbmc_thermal_control);
ABSL_DECLARE_FLAG(bool, enable_fast_sanity);
ABSL_DECLARE_FLAG(std::string, entity_config_location);
ABSL_DECLARE_FLAG(std::string, server_cert_path);
ABSL_DECLARE_FLAG(std::string, server_private_key_path);
ABSL_DECLARE_FLAG(bool, enable_configure_core_count);
ABSL_DECLARE_FLAG(bool, enable_redfish_configure_ifs);
ABSL_DECLARE_FLAG(std::string, smbios_single_host_file_path);
ABSL_DECLARE_FLAG(std::string, smbios_multihost_host_file_path_prefix);

#endif  // BMCWEB_ENABLE_GRPC

#include <memory>
#include <string>

#include "boost/asio/io_context.hpp"  // NOLINT
#include "redfish_devpath_injector.hpp"
#include "google/google_service_nvme.hpp"
#include "google/google_service_root.hpp"
#include "sdbusplus/asio/connection.hpp"

// Default number of Redfish Events stored.
constexpr size_t defaultRedfishEventStoreSize = 1000;

inline void setupSocket(crow::App& app) {
  constexpr uint16_t defaultPort = 18080;
  int listenFd = sd_listen_fds(0);
  uint16_t portNumber = defaultPort;
#ifdef BMCWEB_ENABLE_GRPC
  portNumber = static_cast<uint16_t>(
      absl::GetFlag(FLAGS_httpport).value_or(defaultPort));
#endif

  BMCWEB_LOG_ALWAYS << "setupSocket: defaultPort: " << defaultPort
                    << " portNumber: " << portNumber
                    << " listenFd: " << listenFd;

  if (1 == listenFd) {
    BMCWEB_LOG_INFO << "attempting systemd socket activation";
    if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1, 0) !=
        0) {
      BMCWEB_LOG_INFO << "Starting webserver on socket handle "
                      << SD_LISTEN_FDS_START;
      app.socket(SD_LISTEN_FDS_START);
    } else {
      BMCWEB_LOG_ERROR << "bad incoming socket, starting webserver on port "
                       << portNumber;
      app.port(portNumber);
    }
  } else {
    BMCWEB_LOG_INFO << "Starting webserver on port: " << portNumber;
    app.port(portNumber);
  }
}

inline std::shared_ptr<milotic_tlbmc::SystemRegistryImpl>
createSystemRegistryImpl() {
  milotic_tlbmc::SystemRegistryImpl::Config config{};
#ifdef ENABLE_CONFIGURE_CORE_COUNT
  config.bios_config_config =
      std::make_unique<::platforms::gbmc::hal::BiosConfigConfig>();
#endif
  absl::StatusOr<std::shared_ptr<milotic_tlbmc::SystemRegistryImpl>>
      system_registry = milotic_tlbmc::SystemRegistryImpl::Create(config);

  if (!system_registry.ok()) {
    LOG(WARNING) << "Failed to create system registry: "
                 << system_registry.status();
    return nullptr;
  }
  return *system_registry;
}

inline std::shared_ptr<milotic_tlbmc::CredentialManager>
createCredentialManagerImpl(
    const milotic::RedfishServiceConfig& config,
    const milotic_tlbmc::CredentialManagerImpl::CredentialManagerParams*
        custom_params = nullptr) {
  if (custom_params != nullptr) {
    absl::StatusOr<std::unique_ptr<milotic_tlbmc::CredentialManager>>
        credential_manager =
            milotic_tlbmc::CredentialManagerImpl::Create(*custom_params);
    if (!credential_manager.ok()) {
      LOG(WARNING) << "Failed to create credential manager: "
                   << credential_manager.status();
      return nullptr;
    }
    return *std::move(credential_manager);
  }

  milotic_tlbmc::CredentialManagerImpl::CredentialManagerParams params{
      .private_key_path = config.private_key_path,
      .cert_path = config.own_cert_path,
      .owner_verification_cert_path = config.owner_verification_cert_path,
      .owner_verification_config_path = config.owner_verification_config_path,
      .bmc_ssh_trusted_user_ca_keys_path =
          config.bmc_ssh_trusted_user_ca_keys_path,
      .trust_bundle_path = config.trust_bundle_path,
      .trust_bundle_signature_path = config.trust_bundle_signature_path,
      .os_verification_cert_path = config.os_verification_cert_path,
      .os_verification_key_path = config.os_verification_key_path,
      .serial_console_trusted_user_ca_keys_path =
          config.serial_console_trusted_user_ca_keys_path,
      .serial_console_detatched_signature_path =
          config.serial_console_detatched_signature_path,
      .serial_console_access_level_dir = config.serial_console_access_level_dir,
      .syslog_client_conf_override_path =
          config.syslog_client_conf_override_path,
      .syslog_root_cert_path = config.syslog_root_cert_path,
  };
  absl::StatusOr<std::unique_ptr<milotic_tlbmc::CredentialManager>>
      credential_manager = milotic_tlbmc::CredentialManagerImpl::Create(params);
  if (!credential_manager.ok()) {
    LOG(WARNING) << "Failed to create credential manager: "
                 << credential_manager.status();
    return nullptr;
  }
  return *std::move(credential_manager);
}

inline int run() {
  // First so even startup-path exceptions terminate with a throw-site stack.
  // Also the explicit reference that pulls the tracer TU (and its __cxa_throw
  // interposer) out of the bmcweblib archive despite --gc-sections.
#ifdef BMCWEB_ENABLE_EXCEPTION_STACK_TRACER
  installExceptionStackTracer(absl::GetFlag(FLAGS_exception_stack_tracer));
#endif  // BMCWEB_ENABLE_EXCEPTION_STACK_TRACER
  std::shared_ptr<milotic_tlbmc::CredentialManager> credential_manager =
      nullptr;
#ifdef BMCWEB_ENABLE_GRPC
  absl::InitializeLog();

  std::shared_ptr<milotic_tlbmc::SystemRegistry> system_registry =
      createSystemRegistryImpl();
#ifdef ENABLE_CONFIGURE_CORE_COUNT
  absl::Status status = system_registry->SetInitialCoreCounts();
  if (!status.ok()) {
    LOG(WARNING) << "Failed to set initial core counts: " << status;
  }
#endif

  milotic::RedfishServiceConfig secure_service_config;
  secure_service_config.port = absl::GetFlag(FLAGS_mtls_grpc_port);
  secure_service_config.private_key_path =
      absl::GetFlag(FLAGS_server_private_key_path);
  secure_service_config.own_cert_path = absl::GetFlag(FLAGS_server_cert_path);
  secure_service_config.tlbmc_entity_config_location =
      absl::GetFlag(FLAGS_entity_config_location);
  secure_service_config.smbios_single_host_file_path =
      absl::GetFlag(FLAGS_smbios_single_host_file_path);
  secure_service_config.smbios_multihost_host_file_path_prefix =
      absl::GetFlag(FLAGS_smbios_multihost_host_file_path_prefix);
  secure_service_config.multi_thread_get =
      absl::GetFlag(FLAGS_multi_thread_get);
  secure_service_config.enable_tlbmc = absl::GetFlag(FLAGS_enable_tlbmc);
  secure_service_config.generate_testing_events =
      absl::GetFlag(FLAGS_testing_events);
  secure_service_config.enable_fast_sanity =
      absl::GetFlag(FLAGS_enable_fast_sanity);
  secure_service_config.enable_hft_test_sensor = true;
  secure_service_config.enable_tlbmc_trace =
      absl::GetFlag(FLAGS_enable_tlbmc_trace);
  secure_service_config.enable_tlbmc_thermal_control =
      absl::GetFlag(FLAGS_enable_tlbmc_thermal_control);
  secure_service_config.tlbmc_defer_router_registration_and_validation = true;
  secure_service_config.system_registry = system_registry;

  credential_manager = createCredentialManagerImpl(secure_service_config);
  secure_service_config.credential_manager = credential_manager;

  std::unique_ptr<milotic_tlbmc::RedfishApp> tlbmc_app =
      milotic::GrpcRedfishService::CreateTlbmcApp(secure_service_config);
#ifdef ENABLE_LOAS3_VALIDATION
  secure_service_config.check_loas3_policy = true;
  LOG(WARNING) << "check_loas3_policy is enabled";
#endif

  auto crowLogLevel = crow::LogLevel::Debug;
  crow::Logger::setLogLevel(crowLogLevel);
  const auto minAbslLogLevel =
      static_cast<absl::LogSeverity>(absl::GetFlag(FLAGS_minloglevel));
  BMCWEB_LOG_ALWAYS << "=> minAbslLogLevel: "
                    << static_cast<int>(minAbslLogLevel);
  switch (minAbslLogLevel) {
    // unfortunately there is no: absl::LogSeverity::kInfo; so kInfo ->
    // Debug for now.
    case absl::LogSeverity::kInfo:
      crowLogLevel = crow::LogLevel::Debug;
      break;
    case absl::LogSeverity::kWarning:
      crowLogLevel = crow::LogLevel::Warning;
      break;
    case absl::LogSeverity::kError:
      crowLogLevel = crow::LogLevel::Error;
      break;
    case absl::LogSeverity::kFatal:
      crowLogLevel = crow::LogLevel::Critical;
      break;

    default:
      crowLogLevel = crow::LogLevel::Error;
      break;
  }
  BMCWEB_LOG_ALWAYS << "=> crowLogLevel: " << static_cast<int>(crowLogLevel);
  crow::Logger::setLogLevel(crowLogLevel);
#else
  crow::Logger::setLogLevel(crow::LogLevel::Debug);
#endif
  auto io = std::make_shared<boost::asio::io_context>();
  bool allowSessionEmpty = false;
#ifdef BMCWEB_INSECURE_DISABLE_AUTHX
  allowSessionEmpty = true;
#endif
  std::unique_ptr<devpath_plugin::RedfishDevpathInjector> devpath_injector =
      nullptr;
  absl::StatusOr<std::unique_ptr<devpath_plugin::RedfishDevpathInjector>>
      injector = devpath_plugin::RedfishDevpathInjector::Create(
          "/usr/share/redfish_to_uhm_mappings/"
          "redfish_to_uhm_mappings.textproto");
  if (injector.ok()) {
    devpath_injector = std::move(*injector);
    BMCWEB_LOG_ALWAYS << "RedfishDevpathInjector successfully initialized from "
                         "/usr/share/redfish_to_uhm_mappings/"
                         "redfish_to_uhm_mappings.textproto";
  } else {
    BMCWEB_LOG_ERROR << "Failed to initialize RedfishDevpathInjector: "
                     << injector.status().message();
  }
  App app(allowSessionEmpty, io, tlbmc_app.get(), devpath_injector.get());
  crow::globalBmcWebApp = &app;

  std::shared_ptr<sdbusplus::asio::connection> systemBusPtr =
      std::make_shared<sdbusplus::asio::connection>(*io);

#ifdef BMCWEB_ENABLE_GRPC
  BMCWEB_LOG_STATEFUL_ALWAYS << "=> stateful: "
                             << absl::GetFlag(FLAGS_stateful).value_or(false);
#endif

  managedStore::ManagedObjectStoreConfig config;
  // default to the compiler flag:
#ifdef BMCWEB_ENABLE_STATEFUL_BMCWEB
  config.isEnabled = true;
#else
  config.isEnabled = false;
#endif

// request stats config:
#ifdef BMCWEB_ENABLE_GRPC
  {
    const auto& persistentDataConfig = persistent_data::getConfig();
    managedStore::RequestStatsStoreConfig requestStatsConfig;
    requestStatsConfig.enable = false;
    requestStatsConfig.enableRdeRateLimit = false;

    // command line first:
    if (absl::GetFlag(FLAGS_request_stats).has_value()) {
      requestStatsConfig.enable =
          absl::GetFlag(FLAGS_request_stats).value_or(false);
    }

    // enable rde rate limiter
    if (absl::GetFlag(FLAGS_rde_ratelimit).has_value()) {
      requestStatsConfig.enableRdeRateLimit =
          absl::GetFlag(FLAGS_rde_ratelimit).value_or(false);
    }
    if (absl::GetFlag(FLAGS_rde_errors_max).has_value()) {
      requestStatsConfig.rdeDbusErrorThreshold =
          absl::GetFlag(FLAGS_rde_errors_max).value_or(10);
    }
    if (absl::GetFlag(FLAGS_rde_skips_max).has_value()) {
      requestStatsConfig.rdeMaxSkips =
          absl::GetFlag(FLAGS_rde_skips_max).value_or(30);
    } else if (persistentDataConfig.isStatefulEnabled
                   .has_value()) {  // persistent config:
      requestStatsConfig.enable =
          persistentDataConfig.isRequestStatsEnabled.value();
    }
    BMCWEB_LOG_STATEFUL_ALWAYS << "=> request_stats: "
                               << requestStatsConfig.toJson();
    managedStore::RequestStatsStore::initialize(requestStatsConfig);
  }
#endif

// stateful logs:
#ifdef BMCWEB_ENABLE_GRPC
  {
    const auto& persistentDataConfig = persistent_data::getConfig();
    bool enable_stateful_logs = false;
    // command line first:
    if (absl::GetFlag(FLAGS_stateful_logs).has_value()) {
      enable_stateful_logs = absl::GetFlag(FLAGS_stateful_logs).value_or(false);
    } else if (persistentDataConfig.isStatefulLogsEnabled
                   .has_value()) {  // persistent config:
      enable_stateful_logs = persistentDataConfig.isStatefulLogsEnabled.value();
    }
    BMCWEB_LOG_STATEFUL_ALWAYS << "=> stateful_logs flag: "
                               << enable_stateful_logs;
    if (enable_stateful_logs) {
      crow::Logger::enableStatefulLogs();
    }
  }
#endif

// stateful config:
#ifdef BMCWEB_ENABLE_GRPC
  // command line is always higher priority if set:
  if (absl::GetFlag(FLAGS_stateful).has_value()) {
    config.isEnabled = absl::GetFlag(FLAGS_stateful).value();
  } else  // NOLINT
#endif
  {
    // read the persistent data config:
    const auto& persistentDataConfig = persistent_data::getConfig();
    if (persistentDataConfig.isStatefulEnabled.has_value()) {
      config.isEnabled = persistentDataConfig.isStatefulEnabled.value();
    }
  }

#ifdef BMCWEB_ENABLE_GRPC
  // other flags:
  if (absl::GetFlag(FLAGS_stateful_pending_max).has_value()) {
    config.pendingDbusResponsesMax = static_cast<uint64_t>(
        absl::GetFlag(FLAGS_stateful_pending_max).value());
  }
  if (absl::GetFlag(FLAGS_stateful_tfixed_sec).has_value()) {
    config.tfixedThreshold =
        std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tfixed_sec).value());
  }
  if (absl::GetFlag(FLAGS_stateful_tgrace_sec).has_value()) {
    config.tgraceThreshold =
        std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tgrace_sec).value());
  }
  if (absl::GetFlag(FLAGS_stateful_tlru_sec).has_value()) {
    config.tLRUThreshold =
        std::chrono::seconds(absl::GetFlag(FLAGS_stateful_tlru_sec).value());
  }
  if (absl::GetFlag(FLAGS_timetrace).has_value()) {
    config.timetrace = absl::GetFlag(FLAGS_timetrace).value();
  }
  if (absl::GetFlag(FLAGS_timetrace_size_max).has_value()) {
    config.timetrace_size_max = absl::GetFlag(FLAGS_timetrace_size_max).value();
  }
#endif

  BMCWEB_LOG_STATEFUL_ALWAYS << "=> ManagedObjectStoreConfig: "
                             << config.toString();

#ifndef BMCWEB_ENABLE_STATEFUL_BMCWEB
  if (config.isEnabled) {
    BMCWEB_LOG_WARNING
        << "ManagedObjectStore can't be enabled without "
        << "BMCWEB_ENABLE_STATEFUL_BMCWEB; reverting to stateful=0";
    config.isEnabled = false;
  }
#endif  // BMCWEB_ENABLE_STATEFUL_BMCWEB

  setupSocket(app);

  std::unique_ptr<ecclesia::SubscriptionService> subscriptionService = nullptr;

#ifdef BMCWEB_ENABLE_GRPC
  bool enableRedfishEvents = absl::GetFlag(FLAGS_redfish_events);
  size_t number_of_events_stored = defaultRedfishEventStoreSize;
  if (absl::GetFlag(FLAGS_redfish_event_store_size).has_value()) {
    number_of_events_stored =
        absl::GetFlag(FLAGS_redfish_event_store_size).value();
  }

  using ::milotic::GrpcRedfishService;
  using ::milotic::RedfishServiceConfig;

  if (enableRedfishEvents) {
    BMCWEB_LOG_ALWAYS << "Redfish events enabled\n";
    subscriptionService = CreateSubscriptionService(
        milotic::BmcWebBackend::Create(&app),
        ecclesia::CreateSubscriptionStore(),
        ecclesia::CreateEventStore(number_of_events_stored));
  }
#endif
  // ManagedStore should be initialized regardless of whether grpc is enabled
  auto io_worker_threads = std::make_shared<boost::asio::io_context>();
  uint num_workers = std::thread::hardware_concurrency();
  boost::asio::thread_pool worker_threads(num_workers);
  boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
      work_guard_worker_threads(
          boost::asio::make_work_guard(*io_worker_threads));
  boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
      work_guard_main_thread(boost::asio::make_work_guard(*io));
  for (uint i = 0; i < num_workers; ++i) {
    boost::asio::post(worker_threads,
                      [io_worker_threads]() { io_worker_threads->run(); });
  }
  managedStore::InitializeManagedStore(&config, io.get(), io_worker_threads,
                                       subscriptionService.get(),
                                       systemBusPtr.get(), system_registry);

  // Static assets need to be initialized before Authorization, because auth
  // needs to build the whitelist from the static routes
#ifdef BMCWEB_ENABLE_STATIC_HOSTING
  crow::webassets::requestRoutes(app);
#endif

#ifdef BMCWEB_ENABLE_REDFISH
  redfish::RedfishService redfish(app);
#endif

#ifdef BMCWEB_ENABLE_DBUS_REST
  crow::image_upload::requestRoutes(app);
  crow::openbmc_mapper::requestRoutes(app);
#endif

#ifdef BMCWEB_ENABLE_GOOGLE_API
  crow::google_api::setupCredentialManager(credential_manager);
  crow::google_api::requestRoutes(app);
  crow::google_api::requestGoogleNVMeCollection(app);
  crow::google_api::requestGoogleNVMe(app);
  crow::google_api::requestGoogleNVMeController(app);
  crow::google_api::requestGoogleNVMeControllerCollection(app);
  crow::google_api::setupGoogleNVMeFdFetchIOContext(io);
  crow::google_api::requestGoogleNVMeControllerActionIdentify(app);
  crow::google_api::requestGoogleNVMeControllerActionLog(app);
  crow::google_api::requestGoogleNVMeControllerActionCustomNVMeIdentify(app);
  crow::google_api::requestGoogleNVMeControllerActionAdminNonData(app);
  crow::google_api::requestGoogleNVMeControllerActionLockdownInband(app);
#endif

  if (bmcwebInsecureDisableXssPrevention != 0) {
    cors_preflight::requestRoutes(app);
  }

#ifdef BMCWEB_ENABLE_GRPC
#ifdef BMCWEB_ENABLE_INSECURE_GRPC
  std::cerr << "insecure grpc opened!\n";
  RedfishServiceConfig insecure_config{
      .port = absl::GetFlag(FLAGS_insecure_grpc_port),
      .self_signed_key_cert_path = "/var/volatile/self_signed_key_cert2.pem",
      .tlbmc_entity_config_location =
          absl::GetFlag(FLAGS_entity_config_location),
      .smbios_single_host_file_path =
          absl::GetFlag(FLAGS_smbios_single_host_file_path),
      .smbios_multihost_host_file_path_prefix =
          absl::GetFlag(FLAGS_smbios_multihost_host_file_path_prefix),
      .multi_thread_get = absl::GetFlag(FLAGS_multi_thread_get),
      .enable_tlbmc = absl::GetFlag(FLAGS_enable_tlbmc),
      .enable_insecure_server = true,
      .enable_fast_sanity = absl::GetFlag(FLAGS_enable_fast_sanity),
      .enable_tlbmc_thermal_control =
          absl::GetFlag(FLAGS_enable_tlbmc_thermal_control),
      .tlbmc_defer_router_registration_and_validation = true,
      .system_registry = system_registry,
      .credential_manager = credential_manager,
  };
  GrpcRedfishService insecure_grpc_service(
      &app, tlbmc_app.get(), io, io_worker_threads, insecure_config, nullptr);
#endif
  GrpcRedfishService grpc_service(&app, tlbmc_app.get(), io, io_worker_threads,
                                  secure_service_config,
                                  subscriptionService.get());
#endif
  // Register tlBMC append plugins before gBMCWeb plugins
  GrpcRedfishService::RegisterTlbmcRoutesAndValidate(tlbmc_app.get());

// These have to be registered after managedStore initialization
#ifdef BMCWEB_ENABLE_SSL
  BMCWEB_LOG_INFO << "Start Hostname Monitor Service...";
  crow::hostname_monitor::registerHostnameSignal();
#endif

  bmcweb::registerUserRemovedSignal();

#ifdef PLATFORM_PLUGINS_ENABLED
  redfish_plugin::loadPlatformPlugins();
#endif

#ifdef GOOGLE_COMMON_PLUGINS_ENABLED
  redfish_plugin::loadGooglePlugins();
#endif

#ifdef GOOGLE_PLUGINS_INTERNAL_ENABLED
  redfish_plugin::loadGooglePluginsInternal();
#endif

#ifdef HEALTH_POPULATE
  redfish::HealthStatusCache::getInstance();

#ifndef UNIT_TEST_BUILD
  /*
   * This call subscribes to a live D-Bus signal from the HealthMonitor.
   * This directive excludes the live subscription call during the unit test
   * build, allowing the test to verify logic without attempting to create
   * a real signal match which does not exist in the test environment.
   */
  managedStore::GetManagedObjectStore()->subscribeToEntityManagerChange(
      [](const std::string& objPath) {
        redfish::HealthStatusCache::getInstance().getHealthAttributes(objPath);
      });
#endif /* UNIT_TEST_BUILD */
#endif /* HEALTH_POPULATE */

  app.validate();

  sd_notify(0, "READY=1");

  app.run();

// This will block forever, so skipping these in unit test builds
#ifndef UNIT_TEST_BUILD
  io->run();
  io_worker_threads->stop();
  worker_threads.join();
#endif

  return 0;
}

#endif  // THIRD_PARTY_GBMCWEB_INCLUDE_WEB_SERVER_MAIN_SETUP_H_
