#include "device.hpp"

#include "common/pldm/pldm_package_util.hpp"
#include "software.hpp"
#include "software_manager.hpp"

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/async/context.hpp>
#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <xyz/openbmc_project/Software/ActivationProgress/aserver.hpp>
#include <xyz/openbmc_project/State/Host/client.hpp>

#include <utility>

PHOSPHOR_LOG2_USING;

using namespace phosphor::software::device;

using SoftwareActivationProgress =
    sdbusplus::aserver::xyz::openbmc_project::software::ActivationProgress<
        phosphor::software::Software>;

using SoftwareActivationProgressProperties = sdbusplus::common::xyz::
    openbmc_project::software::ActivationProgress::properties_t;

const auto applyTimeImmediate = sdbusplus::common::xyz::openbmc_project::
    software::ApplyTime::RequestedApplyTimes::Immediate;

const auto ActivationInvalid = ActivationInterface::Activations::Invalid;
const auto ActivationFailed = ActivationInterface::Activations::Failed;

Device::Device(sdbusplus::async::context& ctx, const SoftwareConfig& config,
               manager::SoftwareManager* parent,
               std::set<RequestedApplyTimes> allowedApplyTimes =
                   {RequestedApplyTimes::Immediate,
                    RequestedApplyTimes::OnReset}) :
    allowedApplyTimes(std::move(allowedApplyTimes)), config(config),
    parent(parent), ctx(ctx)
{}

sdbusplus::async::task<bool> Device::getImageInfo(
    std::unique_ptr<void, std::function<void(void*)>>& pldmPackage,
    size_t pldmPackageSize, uint8_t** matchingComponentImage,
    size_t* componentImageSize, std::string& componentVersion)

{
    std::shared_ptr<PackageParser> packageParser =
        pldm_package_util::parsePLDMPackage(
            static_cast<uint8_t*>(pldmPackage.get()), pldmPackageSize);

    if (packageParser == nullptr)
    {
        error("could not parse PLDM package");
        co_return false;
    }

    uint32_t componentOffset = 0;
    const int status = pldm_package_util::extractMatchingComponentImage(
        packageParser, config.compatibleHardware, config.vendorIANA,
        &componentOffset, componentImageSize, componentVersion);

    if (status != 0)
    {
        error("could not extract matching component image");
        co_return false;
    }

    *matchingComponentImage =
        static_cast<uint8_t*>(pldmPackage.get()) + componentOffset;

    co_return true;
}

sdbusplus::async::task<bool> Device::startUpdateAsync(
    sdbusplus::message::unix_fd image, RequestedApplyTimes applyTime,
    std::unique_ptr<Software> softwarePendingIn)
{
    debug("starting the async update with memfd {FD}", "FD", image.fd);

    size_t pldm_pkg_size = 0;
    auto pldm_pkg = pldm_package_util::mmapImagePackage(image, &pldm_pkg_size);

    if (pldm_pkg == nullptr)
    {
        softwarePendingIn->setActivation(ActivationInvalid);
        co_return false;
    }

    uint8_t* componentImage;
    size_t componentImageSize = 0;
    std::string componentVersion;

    if (!co_await getImageInfo(pldm_pkg, pldm_pkg_size, &componentImage,
                               &componentImageSize, componentVersion))
    {
        error("could not extract matching component image");
        softwarePendingIn->setActivation(ActivationInvalid);
        co_return false;
    }

    std::unique_ptr<Software> softwarePendingOld = std::move(softwarePending);

    softwarePending = std::move(softwarePendingIn);
    softwarePendingIn = nullptr;

    const bool success = co_await continueUpdateWithMappedPackage(
        componentImage, componentImageSize, componentVersion, applyTime);

    if (!success)
    {
        softwarePending->setActivation(ActivationFailed);
        error("Failed to update the software for {SWID}", "SWID",
              softwareCurrent->swid);

        softwarePending = std::move(softwarePendingOld);

        co_return false;
    }

    if (applyTime == RequestedApplyTimes::Immediate)
    {
        softwareCurrent = std::move(softwarePending);

        // In case an immediate update is triggered after an update for
        // onReset.
        softwarePending = nullptr;

        debug("Successfully updated to software version {SWID}", "SWID",
              softwareCurrent->swid);
    }

    co_return true;
}

std::string Device::getEMConfigType() const
{
    return config.configType;
}

sdbusplus::async::task<bool> Device::resetDevice()
{
    debug("Default implementation for device reset");

    co_return true;
}

bool Device::setUpdateProgress(uint8_t progress) const
{
    if (!softwarePending || !softwarePending->softwareActivationProgress)
    {
        return false;
    }

    softwarePending->softwareActivationProgress->progress(progress);

    return true;
}

sdbusplus::async::task<bool> Device::continueUpdateWithMappedPackage(
    const uint8_t* matchingComponentImage, size_t componentImageSize,
    const std::string& componentVersion, RequestedApplyTimes applyTime)
{
    softwarePending->setActivation(ActivationInterface::Activations::Ready);

    softwarePending->setVersion(componentVersion,
                                softwareCurrent->getPurpose().value_or(
                                    SoftwareVersion::VersionPurpose::Unknown));

    std::string objPath = softwarePending->objectPath;

    softwarePending->softwareActivationProgress =
        std::make_unique<SoftwareActivationProgress>(
            ctx, objPath.c_str(), SoftwareActivationProgressProperties{0});

    softwarePending->softwareActivationProgress->emit_added();

    softwarePending->setActivationBlocksTransition(true);

    softwarePending->setActivation(
        ActivationInterface::Activations::Activating);

    bool success =
        co_await updateDevice(matchingComponentImage, componentImageSize);

    if (success)
    {
        softwarePending->setActivation(
            ActivationInterface::Activations::Active);
    }

    softwarePending->setActivationBlocksTransition(false);

    softwarePending->softwareActivationProgress = nullptr;

    if (!success)
    {
        // do not apply the update, it has failed.
        // We can delete the new software version.

        co_return false;
    }

    if (applyTime == applyTimeImmediate)
    {
        co_await resetDevice();

        co_await softwarePending->createInventoryAssociations(true);

        softwarePending->enableUpdate(allowedApplyTimes);
    }
    else
    {
        co_await softwarePending->createInventoryAssociations(false);
    }

    co_return true;
}
