// 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 "firmware_updater_interface.hpp"
#include "host_command.hpp"

#include <boost/endian/arithmetic.hpp>

#include <array>
#include <cstdint>

namespace google
{
namespace hoth
{
namespace internal
{
using boost::endian::little_uint16_t;
using boost::endian::little_uint32_t;

/** @brief Equivalent of `hoth_update_region_response` in
 *  google3/host_commands.h
 */
struct HothUpdateRegionResponse
{
    little_uint32_t offset;
    little_uint32_t len;
    uint8_t flags;
};

/** @brief Equivalent of `ec_response_sps_passthrough_status` in
 *  google3/host_commands.h
 */
struct SpsPassthroughStatusResponse
{
    uint8_t enabled;
    std::array<uint8_t, 3> padding;
};

/** @brief Equivalent of `ec_spi_operation_request` in
 *  google3/host_commands.h
 */
struct EcSpiOperationHeader
{
    little_uint16_t mosiLen;
    little_uint16_t misoLen;
};

enum class ResetMode : uint8_t
{
    needed,
    never,
    ignore,
    needed_active,
};

/** @class FirmwareSpiUpdater class
 *  @brief Hoth firmware updater using Hoth SPI command
 */
class FirmwareSpiUpdater : public FirmwareUpdater
{
  public:
    using Base = FirmwareUpdater;

    /** @brief A RAII object to prepare and cleanup the spiWrite op(s).
     */
    class SpiWritePreparer
    {
      public:
        SpiWritePreparer(FirmwareSpiUpdater* updater, ResetMode mode);
        SpiWritePreparer(SpiWritePreparer&& preparer) noexcept;
        ~SpiWritePreparer();

        SpiWritePreparer(const SpiWritePreparer&) = delete;
        SpiWritePreparer& operator=(const SpiWritePreparer&) = delete;
        SpiWritePreparer& operator=(SpiWritePreparer&&) = delete;

      private:
        FirmwareSpiUpdater* fwUpdater{nullptr};
        bool setSpsPassThoughDisabled{false};
        bool didResetTarget{false};
        ResetMode resetMode{ResetMode::needed};
    };

    /** @brief Constructor
     *
     *  @param[in] hostCmd       - Reference to the host command interface
     *  @param[in] addressSize   - SPI operation address size
     *  @param[in] targetReset   - Whether to reset target
     *  @param[in] ignoreAddressMode - Ignore address mode change failure
     */
    explicit FirmwareSpiUpdater(HostCommand* hostCmd, uint8_t addressSize = 4,
                       ResetMode targetReset = ResetMode::never,
                       bool ignoreAddressMode = false);

    [[nodiscard]] SpiWritePreparer prepareSpiWrite();

    /** @brief Updates firmware.
     *
     *  @param[in] firmwareData - Hoth firmware image.
     */
    void update(std::vector<uint8_t> firmwareData) override;

    /** @brief SPI write to arbitrary address
     *
     *  @param[in] address - SPI offset to start writing from
     *  @param[in] data - Data to write to the SPI EEPROM
     */
    void spiWrite(uint32_t address, std::vector<uint8_t> data) override;

  private:
    /** @brief Check if update firmware with Hoth is supported
     *  Check firmware update mode supported using Hoth
     *  EC_PRV_CMD_HOTH_GET_REGION_FROM_IMG_DESC command.
     *
     *  @param[in] firmwareSize - Hoth firmware image length.
     *
     *  @return absolute address from which new firmware data can be written
     */
    uint32_t supportUpdateWithHothSpi(uint32_t firmwareSize);

    /** @brief Set/release target from reset
     *  Calls EC_PRV_CMD_HOTH_RESET_TARGET command to reset target
     *
     *  We only need to call this funciton when the build option is enabled.
     *
     *  @param[in] option - one of ec_target_reset_option enums
     */
    void resetTarget(uint8_t option);

    /** @brief Static helper function for RAII target release
     */
    static void releaseTarget(FirmwareSpiUpdater*&& updater) noexcept;

    /** @brief Check whether SPS passthrough is enabled
     *
     * If SPS passthrough is disabled, then we can send SPI commands without
     * having to reset the target.
     *
     * @return true if passthrough is enabled, false if it's disabled
     */
    bool getSpsPassthrough();

    /** @brief Set SPS passthrough mode
     *
     * If SPS passthrough is disabled, then we can send SPI commands without
     * having to reset the target.
     *
     * @param[in] enable - The desired SPS passthough mode.
     * @return indicates if the passthrough mode is successfully set.
     */
    bool setSpsPassthrough(bool enable);

    /** @brief SPI requires erase enough space before write
     *
     *  @param[in] firmwareSize - Hoth firmware image length.
     *  @param[in] address - address to erase
     */
    void erase(size_t firmwareSize, uint32_t address);

    /** @brief Writes firmwara data
     *
     *  @param[in] firmwareData - Hoth firmware image.
     *  @param[in] address - address to write
     */
    void writeData(const std::vector<uint8_t>& firmwareData, uint32_t address);

    /** @brief Reads back data and verifies it matches input firmware
     *
     *  @param[in] firmwareData - Hoth firmware image.
     *  @param[in] address - address to read
     */
    void verifyData(const std::vector<uint8_t>& firmwareData, uint32_t address);

    /** @brief Appends 3 or 4 byte address to `array` depending on `addressSize`
     *
     *  @param[in] array   - byte array
     *  @param[in] address - address
     */
    void appendAddress(std::vector<uint8_t> &array, uint32_t address) const;

    /** @brief The actual firmware update operation.
     *
     *  @param[in] firmwareData - data
     *  @param[in] address - address
     */
    void doUpdate(const std::vector<uint8_t>& data, uint32_t address);

    /** @brief Connection to Hoth for sending and receiving host commands */
    HostCommand* hostCmd;

    /** @brief SPI operation address size, it can be 3 or 4 bytes */
    uint8_t addressSize;

    /** @brief Whether set target to reset before SPI */
    ResetMode targetReset;

    /** @brief Whether to ignore address mode change failure */
    bool ignoreAddressMode;
};
} // namespace internal
} // namespace hoth
} // namespace google
