#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_BIOS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_BIOS_H_

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <exception>
#include <filesystem>  // NOLINT
#include <fstream>
#include <functional>
#include <ios>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "bm_config.h"
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "json_utils.hpp"
#include "sw_utils.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"

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

namespace redfish {

constexpr absl::string_view kPldmServiceName = "xyz.openbmc_project.pldm";
constexpr absl::string_view kPldmObjectPath = "/xyz/openbmc_project/pldm";
constexpr absl::string_view kPldmControlInterface =
    "xyz.openbmc_project.PLDM.control";
constexpr absl::string_view kPldmLoadSingleFileMethod =
    "loadSingleFileAndSyncCache";

std::string biosSettingFilepathFromConfig = BIOS_SETTING_FILE_PATH;  // NOLINT

inline std::string readBiosSettingsIntoBase64(std::string biosSettingBlobPath) {
  // If the path doesn't exist, set the properties to an empty string
  if (!std::filesystem::exists(biosSettingBlobPath)) {
    BMCWEB_LOG_ERROR << "the BIOS setting file doesn't exist, path:"
                     << biosSettingBlobPath;
    return {};
  }
  const auto fileSize = std::filesystem::file_size(biosSettingBlobPath);
  if (fileSize == 0) {
    BMCWEB_LOG_DEBUG << "the BIOS setting file is empty, path:"
                     << biosSettingBlobPath;
    return {};
  }
  // ManagedFd would be nice but stdplus is not included as DEPENDS in gbmcweb
  std::ifstream ifs(biosSettingBlobPath, std::ios::binary);
  ifs.exceptions(std::ifstream::failbit);
  std::vector<char> fileData(fileSize);
  try {
    std::copy(std::istreambuf_iterator<char>(ifs),
              std::istreambuf_iterator<char>(), fileData.begin());
  } catch (std::ios_base::failure& fail) {
    BMCWEB_LOG_ERROR << "Failed to read the BIOS setting file";
    return {};
  }
  return crow::utility::base64encode(
      std::string_view(fileData.data(), fileData.size()));
}

inline std::string resourceIdFromNameString(const std::string& name) {
  // Find out the index of last non digit character(0,1,2,3,4,5,6,7,8,9)
  // assuming the inout has at least one digit so that we can get resource
  // index. For example, system1->1.
  return name.substr(name.find_last_not_of("0123456789") + 1);
}

inline void handleBios(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& systemName, bool multiHost) {
  // systemId should be empty for single host system.
  std::string systemId = multiHost ? resourceIdFromNameString(systemName) : "";

  asyncResp->res.jsonValue["@odata.id"] =
      absl::Substitute("/redfish/v1/Systems/$0/Bios", systemName);
  asyncResp->res.jsonValue["@odata.type"] = "#Bios.v1_1_0.Bios";
  asyncResp->res.jsonValue["Name"] = "BIOS Configuration";
  asyncResp->res.jsonValue["Description"] = "BIOS Configuration Service";
  asyncResp->res.jsonValue["Id"] = "BIOS";
  asyncResp->res.jsonValue["Actions"]["#Bios.ResetBios"] = {
      {"target",
       absl::Substitute("/redfish/v1/Systems/$0/Bios/Actions/Bios.ResetBios",
                        systemName)}};

  // Get the ActiveSoftwareImage and SoftwareImages
  sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, "",
                                       true);

  // Populated BIOS setting blob
  std::string biosSettingFilepath = biosSettingFilepathFromConfig;
  if (multiHost) {
    size_t posHost = biosSettingFilepath.find("host");
    if (posHost == std::string::npos) {
      BMCWEB_LOG_DEBUG << "The BIOS setting file path template is ill-formated"
                       << biosSettingFilepath;
      return;
    }
    // Get index
    int systemIdInt = 0;
    try {
      systemIdInt = std::stoi(systemId);
      // system1 -> /run/soc_firmware/host0/vmtppr.cfg
      // system2 -> /run/soc_firmware/host1/vmtppr.cfg
      systemIdInt -= 1;
    } catch (const std::exception& ex) {
      BMCWEB_LOG_DEBUG << "file to parse systemId " << systemId
                       << ":from string to int, exception:" << ex.what();
      return;
    }

    // insert the index right after "host" i.e. pos + 4
    biosSettingFilepath.insert(posHost + 4, std::to_string(systemIdInt));
  }

  asyncResp->res.jsonValue["Oem"]["Google"]["MemTestBlob"] =
      readBiosSettingsIntoBase64(biosSettingFilepath);
}

/**
 * BiosService class supports handle get method for bios.
 */
inline void handleBiosServiceGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  constexpr std::array<std::string_view, 1> systemInterfaces{
      {"xyz.openbmc_project.Inventory.Item.System"}};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [asyncResp, systemName](const boost::system::error_code& ec,
                              const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }

        // If there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2) {
          if (systemName != "system") {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
          }
          handleBios(asyncResp, systemName, false);
          return;
        }

        // Otherwise find system, e.g. system1, system2
        for (const auto& object : objects) {
          std::string objectName = object.substr(object.rfind('/') + 1);
          // Found system object
          if (systemName == objectName) {
            handleBios(asyncResp, systemName, true);
            return;
          }
        }

        // Could not find system object
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
      });
}

inline void handleBiosSettingPatch(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& biosSettingFilepath, bool multiHost,
    std::optional<std::string> memTestBlob, int systemId = 0) {
  asyncResp->res.result(boost::beast::http::status::no_content);

  std::filesystem::path filePath(biosSettingFilepath);
  if (!std::filesystem::exists(filePath.parent_path())) {
    BMCWEB_LOG_ERROR << "The directory of the BIOS setting file doesn't exist";
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  if (!memTestBlob) {
    BMCWEB_LOG_ERROR << "Payload was null";
    redfish::messages::internalError(asyncResp->res);
    return;
  }
  std::string memTestBlobBase64;
  if (crow::utility::base64Decode(memTestBlob.value_or(""),
                                  memTestBlobBase64) == false) {
    BMCWEB_LOG_ERROR << "Base64 Decoding unsuccessful";
    redfish::messages::internalError(asyncResp->res);
    return;
  }
  try {
    std::ofstream ofs;
    ofs.open(biosSettingFilepath, std::ios::trunc | std::ios::binary);
    ofs.write(reinterpret_cast<char*>(memTestBlobBase64.data()),
              // Get warning if no cast
              // " error: conversion to
              // 'std::streamsize' {aka 'int'} from
              // 'std::__cxx11::basic_string<char>::size_type' {aka
              // 'unsigned int'} may change the sign of the result
              // [-Werror=sign-conversion]"
              static_cast<int>(memTestBlobBase64.size()));
    ofs.close();
  } catch (std::ios_base::failure& fail) {
    BMCWEB_LOG_ERROR << "Failed to write the BIOS setting file";
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  // We are using PLDM to transfer the BIOS file out in multi-host machine.
  // Reload the file content is necessary to guarantee the file content in
  // PLDMd cache is up-to-date.
  if (multiHost) {
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp](const boost::system::error_code& ec) {
          if (ec) {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::internalError(asyncResp->res);
            return;
          }
        },
        std::string(kPldmServiceName) + std::to_string(systemId),
        std::string(kPldmObjectPath), std::string(kPldmControlInterface),
        std::string(kPldmLoadSingleFileMethod),
        static_cast<uint16_t>(BIOS_SETTING_FILE_HANDLE));
  }

  redfish::messages::success(asyncResp->res);
}

inline void patchBiosSettings(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  std::optional<std::string> memTestBlob;
  if (!ENABLE_BIOS_PEER_AUTH_BYPASS && !req.peer_authenticated) {
    redfish::messages::accessDenied(asyncResp->res, "Bios");
    return;
  }

  if (!redfish::json_util::readJsonPatch(
          req, asyncResp->res, "Oem/Google/MemTestBlob", memTestBlob)) {
    BMCWEB_LOG_ERROR << "There was no valid patch payload";
    redfish::messages::internalError(asyncResp->res);
    return;
  }

  constexpr std::array<std::string_view, 1> systemInterfaces{
      {"xyz.openbmc_project.Inventory.Item.System"}};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [asyncResp, systemName, memTestBlob](
          const boost::system::error_code& ec,
          const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }

        std::string biosSettingFilepath = biosSettingFilepathFromConfig;
        // If there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2) {
          if (systemName != "system") {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
          }
          handleBiosSettingPatch(asyncResp, biosSettingFilepath, false,
                                 memTestBlob);
          return;
        }

        // Otherwise find system, e.g. system1, system2
        for (const auto& object : objects) {
          std::string objectName = object.substr(object.rfind('/') + 1);
          // Found system object
          if (systemName == objectName) {
            // Format the actual file path based on systemName
            std::string systemId = resourceIdFromNameString(systemName);
            size_t posHost = biosSettingFilepath.find("host");
            if (posHost == std::string::npos) {
              BMCWEB_LOG_DEBUG
                  << "The BIOS setting file path template is invalid"
                  << biosSettingFilepath;
              messages::internalError(asyncResp->res);
              return;
            }
            // Get index
            int systemIdInt = 0;
            try {
              systemIdInt = std::stoi(systemId);
              // system1 -> /run/soc_firmware/host0/vmtppr.cfg
              // system2 -> /run/soc_firmware/host1/vmtppr.cfg
              systemIdInt -= 1;
            } catch (const std::exception& ex) {
              BMCWEB_LOG_DEBUG
                  << "file to parse systemId " << systemId
                  << ":from string to int, exception:" << ex.what();
              messages::internalError(asyncResp->res);
              return;
            }

            // insert the index right after "host" i.e. pos + 4
            biosSettingFilepath.insert(posHost + 4,
                                       std::to_string(systemIdInt));

            handleBiosSettingPatch(asyncResp, biosSettingFilepath, true,
                                   memTestBlob, systemIdInt);
            return;
          }
        }

        // Could not find system object
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
      });
}

inline void requestRoutesBiosService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Bios/")
      .privileges(redfish::privileges::getBios)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleBiosServiceGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Bios/")
      .privileges(redfish::privileges::patchBios)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(patchBiosSettings, std::ref(app)));
}

/**
 * BiosReset class supports handle POST method for Reset bios.
 * The class retrieves and sends data directly to D-Bus.
 *
 * Function handles POST method request.
 * Analyzes POST body message before sends Reset request data to D-Bus.
 */
inline void handleBiosResetPost(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Failed to reset bios: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
      },
      "org.open_power.Software.Host.Updater", "/xyz/openbmc_project/software",
      "xyz.openbmc_project.Common.FactoryReset", "Reset");
}

inline void requestRoutesBiosReset(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Bios/Actions/Bios.ResetBios/")
      .privileges(redfish::privileges::postBios)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleBiosResetPost, std::ref(app)));
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_BIOS_H_
