// 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_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_
#define SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_

#include <fuchsia/device/llcpp/fidl.h>
#include <fuchsia/hardware/pty/llcpp/fidl.h>
#include <lib/zx/eventpair.h>

#include <fbl/intrusive_double_list.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>

#include "fifo.h"
#include "pty-server.h"

class PtyClient : public fbl::RefCounted<PtyClient>,
                  public fbl::DoublyLinkedListable<fbl::RefPtr<PtyClient>> {
 public:
  // This ctor is only public for the use of fbl::MakeRefCounted.  Use Create()
  // instead.
  PtyClient(fbl::RefPtr<PtyServer> server, uint32_t id, zx::eventpair local, zx::eventpair remote);

  ~PtyClient();

  // Create a new PtyClient.  This method is preferred to the ctor.
  static zx_status_t Create(fbl::RefPtr<PtyServer> server, uint32_t id,
                            fbl::RefPtr<PtyClient>* out);

  zx_status_t Read(void* data, size_t len, size_t* out_actual);
  zx_status_t Write(const void* data, size_t len, size_t* out_actual);
  zx_status_t GetEvent(zx::eventpair* event) { return remote_.duplicate(ZX_RIGHTS_BASIC, event); }

  Fifo* rx_fifo() { return &rx_fifo_; }

  void AssertHangupSignal() {
    ClearSetFlags(0, kFlagPeerClosed);
    local_.signal_peer(fuchsia_device::wire::kDeviceSignalWritable,
                       fuchsia_device::wire::kDeviceSignalHangup);
  }
  void AssertActiveHungup() {
    local_.signal_peer(
        0, fuchsia_hardware_pty::wire::kSignalEvent | fuchsia_device::wire::kDeviceSignalHangup);
  }

  void AssertReadableSignal() {
    local_.signal_peer(0, fuchsia_device::wire::kDeviceSignalReadable);
  }
  void AssertWritableSignal() {
    local_.signal_peer(0, fuchsia_device::wire::kDeviceSignalWritable);
  }
  void AssertEventSignal() {
    static_assert(fuchsia_hardware_pty::wire::kSignalEvent ==
                  fuchsia_device::wire::kDeviceSignalOob);
    local_.signal_peer(0, fuchsia_hardware_pty::wire::kSignalEvent);
  }

  void DeAssertReadableSignal() {
    local_.signal_peer(fuchsia_device::wire::kDeviceSignalReadable, 0);
  }
  void DeAssertWritableSignal() {
    local_.signal_peer(fuchsia_device::wire::kDeviceSignalWritable, 0);
  }
  void DeAssertEventSignal() { local_.signal_peer(fuchsia_hardware_pty::wire::kSignalEvent, 0); }

  void ClearSetFlags(uint32_t clr, uint32_t set) { flags_ = (flags_ & ~clr) | set; }
  uint32_t flags() const { return flags_; }
  [[nodiscard]] bool in_raw_mode() const { return flags_ & kFlagRawMode; }
  [[nodiscard]] bool is_peer_closed() const { return flags_ & kFlagPeerClosed; }

  uint32_t id() const { return id_; }

  // Ensure READABLE/WRITABLE signals are properly asserted based on active
  // status and rx_fifo status.
  void AdjustSignals();

  [[nodiscard]] bool is_active() { return server_->is_active(this); }
  [[nodiscard]] bool is_control() { return server_->is_control(this); }

  const fbl::RefPtr<PtyServer>& server() const { return server_; }

  // Teardown this client
  void Shutdown();

 private:
  zx_status_t WriteChunk(const void* buf, size_t count, size_t* actual);

  const fbl::RefPtr<PtyServer> server_;
  const uint32_t id_;

  // remote_ is signaled to indicate to client connections various status
  // conditions.
  zx::eventpair local_, remote_;

  static constexpr uint32_t kFlagRawMode = 0x00000001u;
  static_assert(kFlagRawMode == fuchsia_hardware_pty::wire::kFeatureRaw);
  static constexpr uint32_t kFlagPeerClosed = 0x00000002u;

  uint32_t flags_ = 0;
  Fifo rx_fifo_;
};

#endif  // SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_
