// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_ETHERNET_DRIVERS_RNDIS_FUNCTION_RNDIS_FUNCTION_H_
#define SRC_CONNECTIVITY_ETHERNET_DRIVERS_RNDIS_FUNCTION_RNDIS_FUNCTION_H_

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fit/function.h>
#include <lib/operation/ethernet.h>
#include <zircon/hw/usb/cdc.h>

#include <array>
#include <queue>
#include <thread>

#include <ddk/protocol/usb.h>
#include <ddktl/device.h>
#include <ddktl/protocol/ethernet.h>
#include <ddktl/protocol/usb/function.h>
#include <fbl/mutex.h>
#include <usb/request-cpp.h>
#include <usb/usb-request.h>
#include <usb/usb.h>

#include "src/connectivity/ethernet/lib/rndis/rndis.h"

class RndisFunction;

using RndisFunctionType = ddk::Device<RndisFunction, ddk::Unbindable, ddk::Suspendable>;

class RndisFunction : public RndisFunctionType,
                      public ddk::UsbFunctionInterfaceProtocol<RndisFunction>,
                      public ddk::EthernetImplProtocol<RndisFunction, ddk::base_protocol> {
 public:
  explicit RndisFunction(zx_device_t* parent)
      : RndisFunctionType(parent),
        loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
        function_(parent) {}

  void DdkUnbind(ddk::UnbindTxn txn);
  void DdkSuspend(ddk::SuspendTxn txn);
  void DdkRelease();

  size_t UsbFunctionInterfaceGetDescriptorsSize();
  void UsbFunctionInterfaceGetDescriptors(void* out_descriptors_buffer, size_t descriptors_size,
                                          size_t* out_descriptors_actual);
  zx_status_t UsbFunctionInterfaceControl(const usb_setup_t* setup, const void* write_buffer,
                                          size_t write_size, void* out_read_buffer,
                                          size_t read_size, size_t* out_read_actual);
  zx_status_t UsbFunctionInterfaceSetConfigured(bool configured, usb_speed_t speed);
  zx_status_t UsbFunctionInterfaceSetInterface(uint8_t interface, uint8_t alt_setting);

  zx_status_t EthernetImplQuery(uint32_t options, ethernet_info_t* info);
  void EthernetImplStop();
  zx_status_t EthernetImplStart(const ethernet_ifc_protocol_t* ifc_);
  void EthernetImplQueueTx(uint32_t options, ethernet_netbuf_t* netbuf,
                           ethernet_impl_queue_tx_callback completion_cb, void* cookie);
  zx_status_t EthernetImplSetParam(uint32_t param, int32_t value, const void* data,
                                   size_t data_size);
  void EthernetImplGetBti(zx::bti* bti) { bti->reset(); }

  static zx_status_t Create(void* ctx, zx_device_t* dev);
  zx_status_t Bind();

 private:
  zx_status_t HandleCommand(const void* buffer, size_t size);
  zx_status_t HandleResponse(void* buffer, size_t size, size_t* actual);
  zx_status_t Halt();
  void Reset();

  std::optional<std::vector<uint8_t>> QueryOid(uint32_t oid, void* input, size_t length);
  zx_status_t SetOid(uint32_t oid, const uint8_t* input, size_t length);

  void Shutdown();
  void ShutdownComplete() __TA_REQUIRES(lock_);

  void ReadComplete(usb_request_t* request);
  void WriteComplete(usb_request_t* request);
  void NotificationComplete(usb_request_t* request);

  void ReceiveLocked(usb::Request<>& request) __TA_REQUIRES(lock_);
  void NotifyLocked() __TA_REQUIRES(lock_);
  void IndicateConnectionStatus(bool connected);

  uint8_t NotificationAddress() { return descriptors_.notification_ep.bEndpointAddress; }
  uint8_t BulkInAddress() { return descriptors_.in_ep.bEndpointAddress; }
  uint8_t BulkOutAddress() { return descriptors_.out_ep.bEndpointAddress; }

  bool Online() const __TA_REQUIRES(lock_) { return ifc_.is_valid() && rndis_ready_; }

  static constexpr size_t kNotificationMaxPacketSize = 8;
  static constexpr size_t kRequestPoolSize = 8;
  static constexpr size_t kMtu = RNDIS_MAX_XFER_SIZE;

  static constexpr uint32_t kVendorId = 0x44070b00;
  static constexpr char kVendorDescription[] = "Google";
  static constexpr uint16_t kVendorDriverVersionMajor = 1;
  static constexpr uint16_t kVendorDriverVersionMinor = 0;

  async::Loop loop_;

  ddk::EthernetIfcProtocolClient ifc_ __TA_GUARDED(lock_);
  ddk::UsbFunctionProtocolClient function_;
  size_t usb_request_size_;

  fbl::Mutex lock_;
  bool rndis_ready_ __TA_GUARDED(lock_) = false;
  bool shutting_down_ __TA_GUARDED(lock_) = false;
  uint32_t link_speed_ __TA_GUARDED(lock_) = 0;
  std::array<uint8_t, ETH_MAC_SIZE> mac_addr_;

  // Stats.
  std::atomic<uint32_t> transmit_ok_ = 0;
  std::atomic<uint32_t> receive_ok_ = 0;
  std::atomic<uint32_t> transmit_errors_ = 0;
  std::atomic<uint32_t> receive_errors_ = 0;
  std::atomic<uint32_t> transmit_no_buffer_ = 0;

  std::queue<std::vector<uint8_t>> control_responses_ __TA_GUARDED(lock_);

  usb::RequestPool<> free_notify_pool_ __TA_GUARDED(lock_);
  usb::RequestPool<> free_read_pool_ __TA_GUARDED(lock_);
  usb::RequestPool<> free_write_pool_ __TA_GUARDED(lock_);

  size_t pending_requests_ __TA_GUARDED(lock_) = 0;

  std::optional<fit::function<void()>> shutdown_callback_;

  usb_request_complete_t read_request_complete_ = {
      .callback =
          [](void* ctx, usb_request_t* request) {
            auto rndis = reinterpret_cast<RndisFunction*>(ctx);
            async::PostTask(rndis->loop_.dispatcher(),
                            [rndis, request]() { rndis->ReadComplete(request); });
          },
      .ctx = this,
  };

  usb_request_complete_t write_request_complete_ = {
      .callback =
          [](void* ctx, usb_request_t* request) {
            auto rndis = reinterpret_cast<RndisFunction*>(ctx);
            async::PostTask(rndis->loop_.dispatcher(),
                            [rndis, request]() { rndis->WriteComplete(request); });
          },
      .ctx = this,
  };

  usb_request_complete_t notification_request_complete_ = {
      .callback =
          [](void* ctx, usb_request_t* request) {
            auto rndis = reinterpret_cast<RndisFunction*>(ctx);
            async::PostTask(rndis->loop_.dispatcher(),
                            [rndis, request]() { rndis->NotificationComplete(request); });
          },
      .ctx = this,
  };

  struct {
    usb_interface_assoc_descriptor_t assoc;
    usb_interface_descriptor_t communication_interface;
    usb_cs_header_interface_descriptor_t cdc_header;
    usb_cs_call_mgmt_interface_descriptor_t call_mgmt;
    usb_cs_abstract_ctrl_mgmt_interface_descriptor_t acm;
    usb_cs_union_interface_descriptor_1_t cdc_union;
    usb_endpoint_descriptor_t notification_ep;

    usb_interface_descriptor_t data_interface;
    usb_endpoint_descriptor_t out_ep;
    usb_endpoint_descriptor_t in_ep;
  } __PACKED descriptors_;
};

#endif  // SRC_CONNECTIVITY_ETHERNET_DRIVERS_RNDIS_FUNCTION_RNDIS_FUNCTION_H_
