// 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 <libusb-1.0/libusb.h>

#include <stdplus/handle/managed.hpp>

#include <chrono>
#include <cstdint>
#include <utility>
#include <vector>

// NOLINTNEXTLINE(cert-dcl58-cpp)
namespace google
{
namespace hoth
{

class LibusbIntf
{
  public:
    virtual ~LibusbIntf() = default;

    virtual int release_interface(libusb_device_handle* handle,
                                  int interface_num) = 0;
    virtual int claim_interface(libusb_device_handle* handle,
                                int interface_num) = 0;
    virtual int bulk_transfer(libusb_device_handle* dev_handle,
                              unsigned char endpoint, unsigned char* data,
                              int length, int* transferred,
                              unsigned int timeout) = 0;
    virtual void close(libusb_device_handle* dev_handle) = 0;
    virtual int
        get_active_config_descriptor(libusb_device* dev,
                                     libusb_config_descriptor** config) = 0;
    virtual int get_bus_number(libusb_device* dev) = 0;
    virtual int get_port_numbers(libusb_device* dev, uint8_t* port_numbers,
                                 int port_numbers_len) = 0;
    virtual int open(libusb_device* dev, libusb_device_handle** handle) = 0;
    virtual libusb_device* ref_device(libusb_device* dev) = 0;
    virtual void unref_device(libusb_device* dev) = 0;
    virtual ssize_t get_device_list(libusb_context* ctx,
                                    libusb_device*** list) = 0;
    virtual void free_device_list(libusb_device** list, int unref_devices) = 0;
    virtual void exit(libusb_context* ctx) = 0;
    virtual int init(libusb_context** ctx) = 0;
};

namespace libusb
{

static constexpr uint8_t kTransferTypeBits = 0x03;
static constexpr uint8_t kAddressDirectionBits = 0x80;

class InterfaceClaim
{
  public:
    InterfaceClaim(LibusbIntf* libusb, libusb_device_handle* handle,
                   int interface);

  private:
    static void drop(libusb_device_handle*&& handle, int& interface,
                     LibusbIntf*& libusb);
    libusb_device_handle* init(libusb_device_handle* handle, int interface);

    LibusbIntf* libusb;
    stdplus::Managed<libusb_device_handle*, int, LibusbIntf*>::Handle<drop>
        handle;
};

class DeviceHandle
{
  public:
    DeviceHandle(LibusbIntf* libusb, libusb_device_handle* handle) :
        libusb(libusb), handle(handle, libusb)
    {}
    InterfaceClaim claim_interface(int interface);
    unsigned bulk_transfer(const libusb_endpoint_descriptor& ep, uint8_t* data,
                           size_t size, std::chrono::milliseconds timeout);

  private:
    static void drop(libusb_device_handle*&& handle, LibusbIntf*& libusb);

    LibusbIntf* libusb;
    stdplus::Managed<libusb_device_handle*, LibusbIntf*>::Handle<drop> handle;
};

class Device
{
  public:
    Device(LibusbIntf* libusb, libusb_device* dev) :
        libusb(libusb), dev(dev, libusb)
    {}
    libusb_config_descriptor& get_active_config_descriptor();
    uint8_t get_bus_number();
    std::vector<uint8_t> get_port_numbers();
    DeviceHandle open();

  private:
    static void drop(libusb_device*&& dev, LibusbIntf*& libusb);

    LibusbIntf* libusb;
    stdplus::Managed<libusb_device*, LibusbIntf*>::Handle<drop> dev;
};

class Context
{
  public:
    explicit Context(LibusbIntf* libusb) : libusb(libusb), ctx(init(), libusb)
    {}
    std::vector<Device> get_device_list();

  private:
    libusb_context* init();
    static void drop(libusb_context*&& ctx, LibusbIntf*& libusb);

    LibusbIntf* libusb;
    stdplus::Managed<libusb_context*, LibusbIntf*>::Handle<drop> ctx;
};

} // namespace libusb
} // namespace hoth
} // namespace google
