// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dbus_update_impl.hpp"

#include <fmt/format.h>

#include <optional>
#include <string>
#include <utility>

namespace ipmi_hoth
{
namespace internal
{

stdplus::Cancel DbusUpdateImpl::UpdateFirmware(
    std::string_view hothId, const std::vector<uint8_t>& firmwareData, Cb&& cb)
{
    auto req = newHothdCall(hothId, "UpdateFirmware");
    req.append(firmwareData);
    auto cHothId = std::string(hothId);
    return stdplus::Cancel(new BusCall(req.call_async(
        [cb = std::move(cb), hothId = std::move(cHothId)](
            sdbusplus::message::message m) mutable noexcept {
            if (m.is_method_error())
            {
                auto err = m.get_error();
                fmt::print(stderr, "UpdateFirmware failed on `{}`: {}: {}\n",
                           hothId, err->name, err->message);
                cb(FirmwareUpdateStatus::Error);
                return;
            }
            cb(FirmwareUpdateStatus::InProgress);
        },
        asyncCallTimeout)));
}

stdplus::Cancel
    DbusUpdateImpl::GetFirmwareUpdateStatus(std::string_view hothId, Cb&& cb)
{
    auto req = newHothdCall(hothId, "GetFirmwareUpdateStatus");
    auto cHothId = std::string(hothId);
    return stdplus::Cancel(new BusCall(req.call_async(
        [cb = std::move(cb), hothId = std::move(cHothId)](
            sdbusplus::message::message m) mutable noexcept {
            if (m.is_method_error())
            {
                auto err = m.get_error();
                fmt::print(stderr,
                           "GetFirmwareUpdateStatus failed on `{}`: {}: {}\n",
                           hothId, err->name, err->message);
                cb(FirmwareUpdateStatus::Error);
                return;
            }
            try
            {
                std::string rsp;
                m.read(rsp);
                cb(sdbusplus::xyz::openbmc_project::Control::server::Hoth::
                       convertFirmwareUpdateStatusFromString(rsp));
            }
            catch (const std::exception& e)
            {
                fmt::print(
                    stderr,
                    "GetFirmwareUpdateStatus failed unpacking on `{}`: {}\n",
                    hothId, e.what());
                cb(FirmwareUpdateStatus::Error);
            }
        },
        asyncCallTimeout)));
}

} // namespace internal

} // namespace ipmi_hoth
