#pragma once
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "generated/enums/resource.hpp"
#include "http/utility.hpp"
#include "managed_store_types.hpp"
#include "utils/dbus_utils.hpp"

#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>

#include <algorithm>
#include <array>
#include <string>
#include <string_view>
#include <vector>

#include "managed_store.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
