// 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 "google3/cr51_image_descriptor.h"
#include "google3/host_commands.h"

#include "host_command.hpp"
#include "message_util.hpp"
#include "payload_update_interface.hpp"
#include "sys.hpp"

#include <stdplus/handle/managed.hpp>

#include <optional>
#include <span>
#include <string>
#include <vector>

namespace google
{
namespace hoth
{
namespace internal
{

// Struct used to send activate request:
struct ActivateRequest
{
    payload_update_packet header;
    payload_update_activate activate;
};

// Struct used to send confirm request:
struct ConfirmRequest
{
    payload_update_packet header;
    payload_update_confirm confirm;
};

// Maximum allowed payload size
constexpr size_t max_packet_size =
    mailbox_size - sizeof(payload_update_packet) - sizeof(ReqHeader);

constexpr size_t kImageDescriptorAlignment = 64 * 1024;

constexpr uint64_t kDescriptorMagic = 0x5f435344474d495f; // "_IMGDSC_"

constexpr uint32_t kSectorSizeBytes = 4096;
constexpr uint32_t kEraseChunkSizeBytes = kSectorSizeBytes * 32;

/** @class PayloadUpdateImpl
 *  @brief PayloadUpdate method implementation
 *  @details Methods to interface with Hoth to perform payload update
 */
class PayloadUpdateImpl : public PayloadUpdate
{
  public:
    explicit PayloadUpdateImpl(HostCommand* hostCmd,
                               const Sys* sys = &sys_impl) :
        hostCmd(hostCmd), sys(sys)
    {}

    void initiate() const override;
    void erase(uint32_t offset, uint32_t size) const override;
    void eraseAndSendStaticWP(const std::string& path) const override;
    void read(uint32_t offset, std::span<uint8_t> data) const override;
    void verify() const override;
    payload_update_status getStatus() const override;
    void activate(Side side, Persistence persistence) const override;
    void send(const std::string& imagePath) const override;
    std::optional<payload_update_confirm_response>
        confirm(enum payload_update_confirm_option option, uint32_t timeout,
                uint64_t confirmation_cookie) const override;
    bool findDescriptor(const std::string& path, uint32_t* desc_offset) const override;
    void eraseAndSendStaticWPRegions(const std::string& path,
                                     uint32_t desc_offset) const override;
    // Arbitrarily picked due to the performance of the calls taking ~0.4s
    static constexpr size_t verify_size = 512 * 1024;

  private:
    void sendCommand(uint8_t command, uint32_t offset = 0,
                     uint32_t len = 0) const;
    void sendCommand(std::span<const uint8_t> request) const;
    [[nodiscard]] std::span<const uint8_t>
        sendCommand(std::vector<uint8_t>& buf, uint8_t command,
                    uint32_t offset = 0, uint32_t len = 0) const;
    [[nodiscard]] std::span<const uint8_t>
        sendCommand(std::vector<uint8_t>& buf,
                    std::span<const uint8_t> request) const;
    void trimAndSend(std::span<const uint8_t> data,
                     uint32_t globalOffset) const;
    /** @brief RAII wrapper and its destructor for opening a file descriptor */
    static void closeFd(int&& fd, const Sys*& sys)
    {
        if (sys)
        {
            sys->close(fd);
        }
    }
    using Fd = stdplus::Managed<int, const Sys*>::Handle<closeFd>;

    /** @brief Connection to Hoth for sending and receiving host commands */
    HostCommand* hostCmd = nullptr;
    const Sys* sys = nullptr;
};

} // namespace internal

} // namespace hoth

} // namespace google
