// Copyright 2019 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_DEVICES_USB_DRIVERS_XHCI_REWRITE_XHCI_DEVICE_STATE_H_
#define SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_XHCI_DEVICE_STATE_H_

#include <optional>

#include "xhci-hub.h"
#include "xhci-transfer-ring.h"
#include "zircon/compiler.h"

namespace usb_xhci {

// The maximum number of endpoints a USB device can support
constexpr size_t kMaxEndpoints = 32;

class DeviceState {
 public:
  void Disconnect() __TA_REQUIRES(transaction_lock_) { disconnecting_ = true; }

  void reset() __TA_REQUIRES(transaction_lock_) {
    disconnecting_ = true;
    input_context_.reset();
    device_context_.reset();
    slot_ = 0;
    hub_.reset();
    tr_.Deinit();
    for (size_t i = 0; i < kMaxEndpoints; i++) {
      rings_[i].DeinitIfActive();
    }
  }

  void SetDeviceInformation(uint8_t slot, uint8_t port, const std::optional<HubInfo>& hub)
      __TA_REQUIRES(transaction_lock_) {
    slot_ = slot;
    port_ = port;
    hub_ = hub;
    disconnecting_ = false;
  }

  // True if the device state has been initialized, false otherwise.
  bool valid() { return slot_; }

  uint8_t GetPort() { return port_; }

  uint8_t GetSlot() { return slot_; }

  std::optional<HubInfo>& GetHub() __TA_REQUIRES(transaction_lock_) { return hub_; }

  bool IsDisconnecting() __TA_REQUIRES(transaction_lock_) { return disconnecting_; }

  TransferRing& GetTransferRing() __TA_REQUIRES(transaction_lock_) { return tr_; }

  TransferRing& GetTransferRing(size_t endpoint) __TA_REQUIRES(transaction_lock_) {
    return rings_[endpoint];
  }

  std::optional<dma_buffer::PagedBuffer>& GetInputContext() __TA_REQUIRES(transaction_lock_) {
    return input_context_;
  }

  std::optional<dma_buffer::PagedBuffer>& GetDeviceContext() __TA_REQUIRES(transaction_lock_) {
    return device_context_;
  }

  TRBPromise AddressDeviceCommand(UsbXhci* hci, uint8_t slot_id, uint8_t port_id,
                                  std::optional<HubInfo> hub_info, uint64_t* dcbaa,
                                  EventRing* event_ring, CommandRing* command_ring,
                                  ddk::MmioBuffer* mmio, bool bsr);

  zx_status_t InitializeSlotBuffer(const UsbXhci& hci, uint8_t slot_id, uint8_t port_id,
                                   const std::optional<HubInfo>& hub_info,
                                   std::optional<dma_buffer::PagedBuffer>* out);

  zx_status_t InitializeEndpointContext(const UsbXhci& hci, uint8_t slot_id, uint8_t port_id,
                                        const std::optional<HubInfo>& hub_info,
                                        dma_buffer::PagedBuffer* slot_context_buffer)
      __TA_REQUIRES(transaction_lock_);
  zx_status_t InitializeOutputContextBuffer(const UsbXhci& hci, uint8_t slot_id, uint8_t port_id,
                                            const std::optional<HubInfo>& hub_info, uint64_t* dcbaa,
                                            std::optional<dma_buffer::PagedBuffer>* out)
      __TA_REQUIRES(transaction_lock_);

  fbl::Mutex& transaction_lock() __TA_RETURN_CAPABILITY(transaction_lock_) {
    return transaction_lock_;
  }

 private:
  uint8_t slot_ = 0;
  uint8_t port_ = 0;
  fbl::Mutex transaction_lock_;
  std::optional<HubInfo> hub_ __TA_GUARDED(transaction_lock_);
  bool disconnecting_ __TA_GUARDED(transaction_lock_) = false;
  TransferRing tr_ __TA_GUARDED(transaction_lock_);
  TransferRing rings_[kMaxEndpoints] __TA_GUARDED(transaction_lock_);
  std::optional<dma_buffer::PagedBuffer> input_context_ __TA_GUARDED(transaction_lock_);
  std::optional<dma_buffer::PagedBuffer> device_context_ __TA_GUARDED(transaction_lock_);
};
}  // namespace usb_xhci

#endif  // SRC_DEVICES_USB_DRIVERS_XHCI_REWRITE_XHCI_DEVICE_STATE_H_
