#include "software_update.hpp"

#include "device.hpp"
#include "software.hpp"

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/async/context.hpp>
#include <xyz/openbmc_project/Software/Update/aserver.hpp>

PHOSPHOR_LOG2_USING;

using Unavailable = sdbusplus::xyz::openbmc_project::Common::Error::Unavailable;

using namespace phosphor::logging;
using namespace phosphor::software::update;
using namespace phosphor::software::device;
using namespace phosphor::software;

namespace SoftwareLogging = phosphor::logging::xyz::openbmc_project::software;
namespace SoftwareErrors =
    sdbusplus::error::xyz::openbmc_project::software::image;

SoftwareUpdate::SoftwareUpdate(
    sdbusplus::async::context& ctx, const char* path, Software& software,
    const std::set<RequestedApplyTimes>& allowedApplyTimes) :
    sdbusplus::aserver::xyz::openbmc_project::software::Update<SoftwareUpdate>(
        ctx, path),
    software(software), allowedApplyTimes(allowedApplyTimes)
{}

auto SoftwareUpdate::method_call(start_update_t /*unused*/, auto image,
                                 auto applyTime)
    -> sdbusplus::async::task<start_update_t::return_type>
{
    debug("Requesting Image update with {FD}", "FD", image.fd);

    Device& device = software.parentDevice;

    if (device.updateInProgress)
    {
        error("An update is already in progress, cannot update.");
        report<Unavailable>();
        co_return sdbusplus::message::object_path();
    }

    device.updateInProgress = true;

    // check if the apply time is allowed by our device
    if (!allowedApplyTimes.contains(applyTime))
    {
        error(
            "the selected apply time {APPLYTIME} is not allowed by the device",
            "APPLYTIME", applyTime);
        device.updateInProgress = false;
        report<Unavailable>();
        co_return sdbusplus::message::object_path();
    }

    debug("started asynchronous update with fd {FD}", "FD", image.fd);

    int imageDup = dup(image.fd);

    if (imageDup < 0)
    {
        error("ERROR calling dup on fd: {ERR}", "ERR", strerror(errno));
        device.updateInProgress = false;
        co_return software.objectPath;
    }

    debug("starting async update with FD: {FD}\n", "FD", imageDup);

    std::unique_ptr<Software> softwareInstance =
        std::make_unique<Software>(ctx, device);

    softwareInstance->setActivation(ActivationInterface::Activations::NotReady);

    std::string newObjPath = softwareInstance->objectPath;

    // NOLINTBEGIN(readability-static-accessed-through-instance)
    ctx.spawn(
        [](Device& device, int imageDup, RequestedApplyTimes applyTime,
           std::unique_ptr<Software> swupdate) -> sdbusplus::async::task<> {
            co_await device.startUpdateAsync(imageDup, applyTime,
                                             std::move(swupdate));
            device.updateInProgress = false;
            close(imageDup);
            co_return;
        }(device, imageDup, applyTime, std::move(softwareInstance)));
    // NOLINTEND

    // We need the object path for the new software here.
    // It must be the same as constructed during the update process.
    // This is so that bmcweb and redfish clients can keep track of the update
    // process.
    co_return newObjPath;
}

auto SoftwareUpdate::get_property(allowed_apply_times_t /*unused*/) const
{
    return allowedApplyTimes;
}
