#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_SW_UTILS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_SW_UTILS_H_

#pragma once
#include <algorithm>
#include <array>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "boost/system/error_code.hpp"  // NOLINT
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "generated/enums/resource.hpp"
#include "dbus_utils.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

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

namespace redfish {
namespace sw_util {
/* @brief String that indicates a bios software instance */
constexpr const char* biosPurpose =
    "xyz.openbmc_project.Software.Version.VersionPurpose.Host";

/* @brief String that indicates a BMC software instance */
constexpr const char* bmcPurpose =
    "xyz.openbmc_project.Software.Version.VersionPurpose.BMC";

/* @brief String that indicates other firmware instance */
constexpr const char* otherPurpose =
    "xyz.openbmc_project.Software.Version.VersionPurpose.Other";

/**
 * @brief Populate the running software version and image links
 *
 * @param[i,o] aResp             Async response object
 * @param[i]   swVersionPurpose  Indicates what target to look for
 * @param[i]   activeVersionPropName  Index in aResp->res.jsonValue to write
 * the running software version to
 * @param[i]   populateLinkToImages  Populate aResp->res "Links"
 * "ActiveSoftwareImage" with a link to the running software image and
 * "SoftwareImages" with a link to the all its software images
 *
 * @return void
 */
inline void populateSoftwareInformation(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& swVersionPurpose,
    const std::string& activeVersionPropName, const bool populateLinkToImages) {
  // Used later to determine running (known on Redfish as active) Sw images
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  dbus_utils::getAssociationEndPoints(
      "/xyz/openbmc_project/software/functional", requestContext,
      [aResp, swVersionPurpose, activeVersionPropName, populateLinkToImages](
          const boost::system::error_code& ec,
          const dbus::utility::MapperEndPoints& functionalSw) {
        BMCWEB_LOG_DEBUG << "populateSoftwareInformation enter";
        if (ec) {
          BMCWEB_LOG_ERROR << "error_code = " << ec;
          BMCWEB_LOG_ERROR << "error msg = " << ec.message();
          messages::internalError(aResp->res);
          return;
        }

        if (functionalSw.empty()) {
          // Could keep going and try to populate SoftwareImages but
          // something is seriously wrong, so just fail
          BMCWEB_LOG_ERROR << "Zero functional software in system";
          messages::internalError(aResp->res);
          return;
        }

        std::vector<std::string> functionalSwIds;
        // example functionalSw:
        // v as 2 "/xyz/openbmc_project/software/ace821ef"
        //        "/xyz/openbmc_project/software/230fb078"
        for (const auto& sw : functionalSw) {
          sdbusplus::message::object_path path(sw);
          std::string leaf = path.filename();
          if (leaf.empty()) {
            continue;
          }

          functionalSwIds.push_back(leaf);
        }

        constexpr std::array<std::string_view, 1> interfaces = {
            "xyz.openbmc_project.Software.Version"};
        managedStore::ManagedObjectStoreContext requestContext(aResp);
        managedStore::GetManagedObjectStore()->getSubTree(
            "/xyz/openbmc_project/software", 0, interfaces, requestContext,
            [aResp, swVersionPurpose, activeVersionPropName,
             populateLinkToImages, functionalSwIds](
                const boost::system::error_code& ec2,
                const dbus::utility::MapperGetSubTreeResponse& subtree) {
              if (ec2) {
                BMCWEB_LOG_ERROR << "error_code = " << ec2;
                BMCWEB_LOG_ERROR << "error msg = " << ec2.message();
                messages::internalError(aResp->res);
                return;
              }

              BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " images";

              for (const std::pair<std::string,
                                   std::vector<std::pair<
                                       std::string, std::vector<std::string>>>>&
                       obj : subtree) {
                sdbusplus::message::object_path path(obj.first);
                std::string swId = path.filename();
                if (swId.empty()) {
                  messages::internalError(aResp->res);
                  BMCWEB_LOG_ERROR << "Invalid software ID";

                  return;
                }

                bool runningImage = false;
                // Look at Ids from
                // /xyz/openbmc_project/software/functional
                // to determine if this is a running image
                if (std::find(functionalSwIds.begin(), functionalSwIds.end(),
                              swId) != functionalSwIds.end()) {
                  runningImage = true;
                }

                // Now grab its version info
                managedStore::ManagedObjectStoreContext context(aResp);
                managedStore::GetManagedObjectStore()->getAllProperties(
                    obj.second[0].first, obj.first,
                    "xyz.openbmc_project.Software.Version", context,
                    [aResp, swId, runningImage, swVersionPurpose,
                     activeVersionPropName, populateLinkToImages](
                        const boost::system::error_code& ec3,
                        const dbus::utility::DBusPropertiesMap&
                            propertiesList) {
                      if (ec3) {
                        BMCWEB_LOG_ERROR << "error_code = " << ec3;
                        BMCWEB_LOG_ERROR << "error msg = " << ec3.message();
                        // Have seen the code update app delete the D-Bus
                        // object, during code update, between the call to
                        // mapper and here. Just leave these properties off if
                        // resource not found.
                        if (ec3.value() == EBADR) {
                          return;
                        }
                        messages::internalError(aResp->res);
                        return;
                      }
                      // example propertiesList
                      // a{sv} 2 "Version" s
                      // "IBM-witherspoon-OP9-v2.0.10-2.22" "Purpose"
                      // s
                      // "xyz.openbmc_project.Software.Version.VersionPurpose.Host"
                      const std::string* version = nullptr;
                      const std::string* swInvPurpose = nullptr;

                      const bool success = sdbusplus::unpackPropertiesNoThrow(
                          dbus_utils::UnpackErrorPrinter(), propertiesList,
                          "Purpose", swInvPurpose, "Version", version);

                      if (!success) {
                        messages::internalError(aResp->res);
                        return;
                      }

                      if (version == nullptr || version->empty()) {
                        messages::internalError(aResp->res);
                        return;
                      }
                      if (swInvPurpose == nullptr ||
                          *swInvPurpose != swVersionPurpose) {
                        // Not purpose we're looking for
                        return;
                      }

                      BMCWEB_LOG_DEBUG << "Image ID: " << swId;
                      BMCWEB_LOG_DEBUG << "Running image: " << runningImage;
                      BMCWEB_LOG_DEBUG << "Image purpose: " << *swInvPurpose;

                      if (populateLinkToImages) {
                        nlohmann::json& softwareImageMembers =
                            aResp->res.jsonValue["Links"]["SoftwareImages"];
                        // Firmware images are at
                        // /redfish/v1/UpdateService/FirmwareInventory/<Id>
                        // e.g. .../FirmwareInventory/82d3ec86
                        nlohmann::json::object_t member;
                        member["@odata.id"] = crow::utility::urlFromPieces(
                            "redfish", "v1", "UpdateService",
                            "FirmwareInventory", swId);
                        softwareImageMembers.push_back(std::move(member));
                        aResp->res
                            .jsonValue["Links"]["SoftwareImages@odata.count"] =
                            softwareImageMembers.size();

                        if (runningImage) {
                          nlohmann::json::object_t runningMember;
                          runningMember["@odata.id"] =
                              crow::utility::urlFromPieces(
                                  "redfish", "v1", "UpdateService",
                                  "FirmwareInventory", swId);
                          // Create the link to the running image
                          aResp->res.jsonValue["Links"]["ActiveSoftwareImage"] =
                              std::move(runningMember);
                        }
                      }
                      if (!activeVersionPropName.empty() && runningImage) {
                        aResp->res.jsonValue[activeVersionPropName] = *version;
                      }
                    });
              }
            });
      });
}

/**
 * @brief Translate input swState to Redfish state
 *
 * This function will return the corresponding Redfish state
 *
 * @param[i]   swState  The OpenBMC software state
 *
 * @return The corresponding Redfish state
 */
inline resource::State getRedfishSwState(const std::string& swState) {
  if (swState == "xyz.openbmc_project.Software.Activation.Activations.Active") {
    return resource::State::Enabled;
  }
  if (swState ==
      "xyz.openbmc_project.Software.Activation."
      "Activations.Activating") {
    return resource::State::Updating;
  }
  if (swState ==
      "xyz.openbmc_project.Software.Activation."
      "Activations.StandbySpare") {
    return resource::State::StandbySpare;
  }
  BMCWEB_LOG_DEBUG << "Default sw state " << swState << " to Disabled";
  return resource::State::Disabled;
}

/**
 * @brief Translate input swState to Redfish health state
 *
 * This function will return the corresponding Redfish health state
 *
 * @param[i]   swState  The OpenBMC software state
 *
 * @return The corresponding Redfish health state
 */
inline std::string getRedfishSwHealth(const std::string& swState) {
  if ((swState ==
       "xyz.openbmc_project.Software.Activation.Activations.Active") ||
      (swState == "xyz.openbmc_project.Software.Activation.Activations."
                  "Activating") ||
      (swState ==
       "xyz.openbmc_project.Software.Activation.Activations.Ready")) {
    return "OK";
  }
  BMCWEB_LOG_DEBUG << "Sw state " << swState << " to Warning";
  return "Warning";
}

/**
 * @brief Put status of input swId into json response
 *
 * This function will put the appropriate Redfish state of the input
 * software id to ["Status"]["State"] within the json response
 *
 * @param[i,o] aResp    Async response object
 * @param[i]   swId     The software ID to get status for
 * @param[i]   dbusSvc  The dbus service implementing the software object
 *
 * @return void
 */
inline void getSwStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const std::shared_ptr<std::string>& swId,
                        const std::string& dbusSvc) {
  BMCWEB_LOG_DEBUG << "getSwStatus: swId " << *swId << " svc " << dbusSvc;

  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      dbusSvc, "/xyz/openbmc_project/software/" + *swId,
      "xyz.openbmc_project.Software.Activation", context,
      [asyncResp, swId](
          const boost::system::error_code& errorCode,
          const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (errorCode) {
          // not all swtypes are updateable, this is ok
          asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
          return;
        }

        const std::string* swInvActivation = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), propertiesList, "Activation",
            swInvActivation);

        if (!success) {
          messages::internalError(asyncResp->res);
          return;
        }

        if (swInvActivation == nullptr) {
          messages::internalError(asyncResp->res);
          return;
        }

        BMCWEB_LOG_DEBUG << "getSwStatus: Activation " << *swInvActivation;
        asyncResp->res.jsonValue["Status"]["State"] =
            getRedfishSwState(*swInvActivation);
        asyncResp->res.jsonValue["Status"]["Health"] =
            getRedfishSwHealth(*swInvActivation);
      });
}

/**
 * @brief Updates programmable status of input swId into json response
 *
 * This function checks whether software inventory component
 * can be programmable or not and fill's the "Updatable"
 * Property.
 *
 * @param[i,o] asyncResp  Async response object
 * @param[i]   swId       The software ID
 */
inline void getSwUpdatableStatus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::shared_ptr<std::string>& swId) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getAssociationEndPoints(
      "/xyz/openbmc_project/software/updateable", requestContext,
      [asyncResp, swId](const boost::system::error_code& ec,
                        const dbus::utility::MapperEndPoints& objPaths) {
        if (ec) {
          BMCWEB_LOG_DEBUG << " error_code = " << ec
                           << " error msg =  " << ec.message();
          // System can exist with no updateable software,
          // so don't throw error here.
          return;
        }
        std::string reqSwObjPath = "/xyz/openbmc_project/software/" + *swId;

        if (std::find(objPaths.begin(), objPaths.end(), reqSwObjPath) !=
            objPaths.end()) {
          asyncResp->res.jsonValue["Updateable"] = true;
          return;
        }
      });
}

/**
 * @brief Updates programmable settings of input swId into json response
 *
 * This function checks whether firmware inventory component's setting from
 * D-bus. It only looks like the `WriteProtected` property to see if the
 * firmware is write protect.
 *
 * @param[i,o] asyncResp  Async response object
 * @param[i]   service    Service handling the firmware
 * @param[i]   path       D-bus path of the firmware component
 */
inline void getSoftwareSettings(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& service, const std::string& path) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getProperty<bool>(
      service, path, "xyz.openbmc_project.Software.Settings", "WriteProtected",
      requestContext,
      [asyncResp](const boost::system::error_code ec, bool writeProtected) {
        if (ec) {
          // System can exist with no updateable/writable firmware,
          // so don't throw error here.
          BMCWEB_LOG_DEBUG << " getFirmwareSettings error_code = " << ec
                           << " error msg =  " << ec.message();
          return;
        }

        asyncResp->res.jsonValue["WriteProtected"] = writeProtected;
      });
}

}  // namespace sw_util
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_SW_UTILS_H_
