// 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.

#pragma once

#include "ec_util.hpp"
#include "firmware_updater_interface.hpp"
#include "host_command_interface.hpp"
#include "mtd_util_interface.hpp"
#include "payload_update_interface.hpp"
#include "sys_interface.hpp"

#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Control/Hoth/server.hpp>

#include <future>

namespace google
{
namespace hoth
{

template <typename... T>
using ServerObject = typename sdbusplus::server::object::object<T...>;
using HothInterface = sdbusplus::xyz::openbmc_project::Control::server::Hoth;
using HothObject = ServerObject<HothInterface>;

/** @class Hoth
 *  @brief Hoth control interface implementation.
 *  @details A concrete implementation for xyz.openbmc_project.Control.Hoth
 *  DBus API.
 */
class Hoth : public HothObject
{
  public:
    /** @brief Constructs Hoth Control Interface
     *
     *  @param[in] bus             - The Dbus bus object
     *  @param[in] objPath         - The Dbus object path
     *  @param[in] hostCmd         - Reference to the host command interface
     *  @param[in] payloadUpdate   - Reference to the payload update interface
     *  @param[in] ecutil          - Reference to the ec utility interface
     *  @param[in] mtd             - Reference to the MTD utility interface
     *  @param[in] sys             - Reference to the Sys call interface
     *  @param[in] firmwareUpdater - Reference to the firmware updater interface
     */
    Hoth(sdbusplus::bus::bus& bus, const char* objPath,
         internal::HostCommand* hostCmd, internal::PayloadUpdate* payloadUpdate,
         internal::EcUtil* ecutil, internal::FirmwareUpdater* firmwareUpdater) :
        HothObject(bus, objPath),
        hostCmd(hostCmd), payloadUpdate(payloadUpdate), ecUtil(ecutil),
        firmwareUpdater(firmwareUpdater),
        lastFirmwareUpdateStatus(FirmwareUpdateStatus::None),
        lastInitiatePayloadStatus(FirmwareUpdateStatus::None),
        lastSendPayloadStatus(FirmwareUpdateStatus::None),
        lastVerifyPayloadStatus(FirmwareUpdateStatus::None)
    {
        // Nothing to do
    }

    /** @brief Implementation for SendHostCommand
     *  Send a host command to Hoth if it isn't banned and return the
     * response. This will block on Hoth completing its internal operations.
     * This method should be called from the IPMI HostCommand passthrough.
     *
     *  @param[in] command - Data to write to Hoth SPI host command offset.
     *
     *  @return response[std::vector<uint8_t>] - Data read from Hoth SPI host
     * command offset.
     */
    std::vector<uint8_t> sendHostCommand(std::vector<uint8_t> command) override;

    /** @brief Implementation for SendTrustedHostCommand
     *  Send a host command to Hoth and return the response. This will block on
     * Hoth completing its internal operations. This method should be called
     * from the BMC.
     *
     *  @param[in] command - Data to write to Hoth SPI host command offset.
     *
     *  @return response[std::vector<uint8_t>] - Data read from Hoth SPI host
     * command offset.
     */
    std::vector<uint8_t>
        sendTrustedHostCommand(std::vector<uint8_t> command) override;

    /** @brief Implementation for SendHostCommandAsync
     *  Send a host command to Hoth and immediately return without waiting for
     * response. Caller can either poll with calls to GetHostCommandResponse
     * until retrieving the response, or wait for a ResponseReady signal.
     *
     *  @param[in] command - Data to write to Hoth SPI host command offset.
     *
     *  @return callToken[uint64_t] - The representation for the call made, if
     * it was posted
     */
    uint64_t sendHostCommandAsync(std::vector<uint8_t> command) override;

    /** @brief Implementation for GetHostCommandResponse
     *  Read the response from Hoth mailbox.
     *
     *  @param[in] callToken - The token returned from SendHostCommandAsync()
     *
     *  @return response[std::vector<uint8_t>] - Data read from Hoth SPI host
     * command offset.
     */
    std::vector<uint8_t> getHostCommandResponse(uint64_t callToken) override;

    /** @brief Implementation for UpdateFirmware
     *  Write given firmware data to the Hoth firmware partition in EEPROM.
     *
     *  @param[in] firmwareData - Hoth firmware image.
     */
    void updateFirmware(std::vector<uint8_t> firmwareData) override;

    /** @brief Implementation for SpiWrite
     * Write the byte data to the specified address in EEPROM.
     *
     *  @param[in] address - Address to start writing from
     *  @param[in] data - Data to be written
     */
    void spiWrite(uint32_t address, std::vector<uint8_t> data) override;

    /** @brief Implementation for GetFirmwareUpdateStatus
     *  Get the status of the firmware update process.
     *
     *  @return status[FirmwareUpdateStatus] - Status of the firmware update
     */
    FirmwareUpdateStatus getFirmwareUpdateStatus() override;

    /** @brief Implementation for InitiatePayload
     *  Initiates erasure of the EEPROM staging area. Note that this will lock
     * up access to Hoth for an extended time and may go over the kernel's SPI
     * write timeout. Calling multiple small ErasePayload is recommended.
     */
    void initiatePayload() override;

    /** @brief Implementation for GetInitiatePayloadStatus
     *  Get the status of the payload initiation process.
     *
     *  @return status[FirmwareUpdateStatus] - Status of the payload initiation
     */
    FirmwareUpdateStatus getInitiatePayloadStatus() override;

    /** @brief Implementation for SendPayload
     *  Chunk and send the binary specified in the image path
     *
     *  @param[in] imagePath - Firmware image path
     */
    void sendPayload(std::string imagePath) override;

    /** @brief Implementation for GetSendPayloadStatus
     *  Get the status of the send payload process.
     *
     *  @return status[FirmwareUpdateStatus] - Status of the send payload
     * process.
     */
    FirmwareUpdateStatus getSendPayloadStatus() override;

    /** @brief Implementation for ErasePayload
     *  Erases the given size starting at the specified offset of the staging
     * partition.
     *
     *  @param[in] offset - Offset of the staging partition to start erasing
     * from.
     *  @param[in] size - Size of the staging partition to erase.
     */
    void erasePayload(uint32_t offset, uint32_t size) override;

    /** @brief Implementation for eraseAndSendStaticWPPayload
     *  Erases and writes only the static and write protected regions of the
     * image provided.
     *
     *  @param[in] imagePath - Firmware image path
     */
    void eraseAndSendStaticWPPayload(std::string imagePath) override;

    /** @brief Implementation for VerifyPayload
     *  Initiates the verification process without activating the staging area.
     */
    void verifyPayload() override;

    /** @brief Implementation for GetInitiatePayloadStatus
     *  Get the status of the payload verification process.
     *
     *  @return status[FirmwareUpdateStatus] - Status of the payload
     * verification
     */
    FirmwareUpdateStatus getVerifyPayloadStatus() override;

    /** @brief Implementation for ActivatePayload
     *  Activates the staging area as persistent or non-persistent for next boot
     * if verification was successful.
     *
     *  @param[in] makePersistent - Flag to determine whether to activate the
     * staged image as persistent or non-persistent for next boot.
     */
    void activatePayload(bool makePersistent) override;

    /** @brief Implementation for DeactivatePayload
     *  Deactivates the staging area
     *
     */
    void deactivatePayload() override;

    /** @brief Implementation for GetPayloadSize
     *
     *  @return The size of the payload region
     */
    uint32_t getPayloadSize() override;

    /** @brief Implementation for Confirm
     *  Prevents hoth from rolling back and using the previous image. When an
     *  image can be comfirmed to be working well, this command is given, which
     *  disarms the hoth watchdog.
     */
    void confirm() override;

    /** @brief Implementation for GetTotalBootTime.
     *
     *  @return Time spent in microseconds from reset to HVNGOOD.
     */
    uint32_t getTotalBootTime() override;

    /** @brief Implementation for GetFirmwareUpdateTime.
     *
     *  @return Time spent in microseconds in the self update routine.
     */
    uint32_t getFirmwareUpdateTime() override;

    /** @brief Implementation for GetFirmwareMirroringTime.
     *
     *  @return Time spent in microseconds in mirroing the self-update.
     */
    uint32_t getFirmwareMirroringTime() override;

    /** @brief Implementation for GetPayloadValidationTime.
     *
     *  @return Time spent in microseconds in validating the payload.
     */
    uint32_t getPayloadValidationTime() override;

    /**
     * @brief Implementation for CollectHothLogs
     *
     */
    void collectHothLogs() override;

    /**
     * @brief Trigger Uart log scheduler if not already working over Dbus
     */
    void collectUartLogs() override;

    /**
     * @brief Manual Stop to Uart log scheduler over Dbus
    */
    void stopUartLogs() override;

  private:
    /** @brief Connection to Hoth for sending and receiving host commands */
    internal::HostCommand* hostCmd = nullptr;

    /** @brief Payload object to conduct payload update with Hoth */
    internal::PayloadUpdate* payloadUpdate = nullptr;

    /** @brief EC utility object to access the utility function from Hoth */
    internal::EcUtil* ecUtil = nullptr;

    /** @brief FirmwareUpdater object */
    internal::FirmwareUpdater* firmwareUpdater = nullptr;

    /** @brief Wrapper function to determine the status of an async thread
     *
     * @param[in] asyncFuture - Pointer to the async thread of interest
     * @return status[FirmwareUpdateStatus] - Status of the async thread
     */
    static FirmwareUpdateStatus getAsyncStatus(std::future<void>* asyncFuture);

    /** @brief Check for any ongoing payload async threads
     *  If an ongoing payload async thread is found, throw an exception via elog
     */
    void checkForOngoingPayload();

    /** @brief Check for any ongoing SPI write threads
     *  If an SPI write async thread is found, throw an exception via elog
     */
    void checkForOngoingSpiWrite();

    /** @brief Future object for initiate paylaod */
    std::future<void> futInitiatePayload;

    /** @brief Future object for send payload */
    std::future<void> futSendPayload;

    /** @brief Future object for verify payload */
    std::future<void> futVerifyPayload;

    /** @brief Future object for SPI write */
    std::future<void> futSpiWrite;

    /** @brief Last FirmwareUpdateStatus checked for firmware update */
    FirmwareUpdateStatus lastFirmwareUpdateStatus;

    /** @brief Last FirmwareUpdateStatus checked for initiate payload */
    FirmwareUpdateStatus lastInitiatePayloadStatus;

    /** @brief Last FirmwareUpdateStatus checked for send payload */
    FirmwareUpdateStatus lastSendPayloadStatus;

    /** @brief Last FirmwareUpdateStatus checked for verify payload */
    FirmwareUpdateStatus lastVerifyPayloadStatus;
};

} // namespace hoth
} // namespace google
