// 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 "libhoth_usb.hpp"
#include "libusb.hpp"
#include "message_intf.hpp"
// NOLINTNEXTLINE(cert-dcl58-cpp)
namespace google
{
namespace hoth
{
class MessageHothUSB : public MessageIntf
{
  public:
    explicit MessageHothUSB(std::string_view usb_id, LibusbIntf* libusb,
                            LibHothUsbIntf* libhoth_usb);
    MessageHothUSB(const MessageHothUSB&) = delete;
    MessageHothUSB& operator=(const MessageHothUSB&) = delete;
    MessageHothUSB(MessageHothUSB&&) noexcept;
    MessageHothUSB& operator=(MessageHothUSB&&) noexcept;

    MessageHothUSB& swap(MessageHothUSB& other)
    {
        std::swap(this->libusb_, other.libusb_);
        std::swap(this->ctx_, other.ctx_);
        std::swap(this->dev_, other.dev_);
        std::swap(this->libhoth_usb_, other.libhoth_usb_);
        std::swap(this->hoth_dev_, other.hoth_dev_);
        std::swap(this->buff_, other.buff_);
        return *this;
    }

    void send(const uint8_t* buf, size_t size, size_t seek) override;
    void recv(uint8_t* buf, size_t size, size_t seek) override;
    ~MessageHothUSB() override;

  private:
    LibusbIntf* libusb_;
    libusb_context* ctx_;
    libusb_device* dev_;
    LibHothUsbIntf* libhoth_usb_;
    libhoth_device* hoth_dev_;

    // Max request/response packege for hoth usb tranferring is 1024k.
    constexpr static size_t kMailboxSize = 1024;
    // timeout in milliseconds. The value doesn't matter since hothd will loop
    // and retry on timeout.
    static constexpr int timeout = 1000;
    std::vector<uint8_t> buff_;
};
} // namespace hoth
} // namespace google
