// 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_NETWORK_TUN_NETWORK_TUN_TUN_DEVICE_H_
#define SRC_CONNECTIVITY_NETWORK_TUN_NETWORK_TUN_TUN_DEVICE_H_

#include <fidl/fuchsia.net.tun/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdf/cpp/dispatcher.h>

#include <optional>
#include <queue>

#include <fbl/intrusive_double_list.h>
#include <fbl/mutex.h>

#include "device_adapter.h"
#include "mac_adapter.h"
#include "state.h"

namespace network {
namespace tun {

// Forward declaration for test-only friend class used below.
namespace testing {
class TunTest;
}

// Implements `fuchsia.net.tun.Device`.
//
// `TunDevice` uses `DeviceAdapter` to fulfill the `fuchsia.net.tun.Device` protocol. All FIDL
// requests are served over its own internally held async dispatcher.
class TunDevice : public fbl::DoublyLinkedListable<std::unique_ptr<TunDevice>>,
                  public fidl::WireServer<fuchsia_net_tun::Device>,
                  public DeviceAdapterParent {
 public:
  static constexpr size_t kMaxPendingOps = fuchsia_net_tun::wire::kMaxPendingOperations;

  // Creates a new `TunDevice` with `config`.
  // `teardown` is called when all the bound client channels are closed.
  static zx::result<std::unique_ptr<TunDevice>> Create(
      const DeviceInterfaceDispatchers& dispatchers, const ShimDispatchers& shim_dispatchers,
      fit::callback<void(TunDevice*)> teardown, DeviceConfig&& config);
  ~TunDevice() override;

  // fuchsia.net.tun.Device implementation:
  void WriteFrame(WriteFrameRequestView request, WriteFrameCompleter::Sync& completer) override;
  void ReadFrame(ReadFrameCompleter::Sync& completer) override;
  void GetSignals(GetSignalsCompleter::Sync& completer) override;
  void AddPort(AddPortRequestView request, AddPortCompleter::Sync& _completer) override;
  void GetDevice(GetDeviceRequestView request, GetDeviceCompleter::Sync& _completer) override;

  // DeviceAdapterParent implementation:
  const BaseDeviceConfig& config() const override { return config_; }
  void OnTxAvail(DeviceAdapter* device) override;
  void OnRxAvail(DeviceAdapter* device) override;

  // Binds `req` to this device.
  // Requests are served over this device's owned loop.
  // NOTE: at this moment only one binding is supported, if the device is already bound the previous
  // channel is closed.
  void Bind(fidl::ServerEnd<fuchsia_net_tun::Device> req);

 protected:
  friend testing::TunTest;
  const std::unique_ptr<DeviceAdapter>& adapter() const { return device_; }

 private:
  class Port : public PortAdapterParent, public fidl::WireServer<fuchsia_net_tun::Port> {
   public:
    Port(Port&&) = delete;
    ~Port() override;

    static zx::result<std::unique_ptr<Port>> Create(TunDevice* parent,
                                                    const DevicePortConfig& config);
    // MacAdapterParent implementation:
    void OnMacStateChanged(MacAdapter* adapter) override;

    // PortAdapterParent implementation:
    void OnHasSessionsChanged(PortAdapter& port) override;
    void OnPortStatusChanged(PortAdapter& port, const port_status_t& new_status) override;
    void OnPortDestroyed(PortAdapter& port) override;

    // FIDL port implementation:
    void GetState(GetStateCompleter::Sync& completer) override;
    void WatchState(WatchStateCompleter::Sync& completer) override;
    void SetOnline(SetOnlineRequestView request, SetOnlineCompleter::Sync& completer) override;
    void GetPort(GetPortRequestView request, GetPortCompleter::Sync& _completer) override;
    void Remove(RemoveCompleter::Sync& _completer) override;

    void SetOnline(bool online);
    PortAdapter& adapter() { return *adapter_; }

    void Bind(fidl::ServerEnd<fuchsia_net_tun::Port> req);

   private:
    explicit Port(TunDevice* parent) : parent_(parent) {}
    // Fulfills pending WatchState requests.
    void RunStateChange();
    // Posts |RunStateChange| to run later on parent dispatcher.
    void PostRunStateChange();
    InternalState State() const;

    TunDevice* const parent_;
    std::unique_ptr<PortAdapter> adapter_;
    std::optional<WatchStateCompleter::Async> pending_watch_state_;
    std::optional<InternalState> last_state_;
    std::optional<fidl::ServerBindingRef<fuchsia_net_tun::Port>> binding_;
    std::optional<libsync::Completion> port_destroyed_;
  };

  TunDevice(fdf::Dispatcher* dispatcher, fit::callback<void(TunDevice*)> teardown,
            DeviceConfig&& config);
  // Completes a single WriteFrame request. Returns true iff a reply was sent on the callback.
  template <typename F, typename C>
  bool WriteWith(F fn, C& callback);
  // Fulfills pending WriteFrame requests. Returns true iff all pending requests were processed.
  bool RunWriteFrame();
  // Fulfills pending ReadFrame requests.
  void RunReadFrame();

  // Calls the teardown callback.
  void Teardown();
  bool IsBlocking() const { return config_.blocking; }

  fit::callback<void(TunDevice*)> teardown_callback_;
  const DeviceConfig config_;

  async::Loop loop_;
  std::optional<thrd_t> loop_thread_;
  fdf::Dispatcher* dispatcher_;
  std::optional<fidl::ServerBindingRef<fuchsia_net_tun::Device>> binding_;
  std::unique_ptr<DeviceAdapter> device_;

  std::array<std::unique_ptr<Port>, MAX_PORTS> ports_;

  // Helper struct to store pending write requests.
  struct PendingWriteRequest {
    // Owned fields of fuchsia_net_tun::wire::Frame.
    uint8_t port_id;
    fuchsia_hardware_network::wire::FrameType frame_type;
    std::vector<uint8_t> data;
    // FrameMetadata::info is a fidl::VectorView, so we should really be copying it. At the time of
    // writing, it isn't used.
    std::optional<fuchsia_net_tun::wire::FrameMetadata> meta;

    // The FIDL transaction completer.
    WriteFrameCompleter::Async completer;

    PendingWriteRequest(const fuchsia_net_tun::wire::Frame& frame,
                        WriteFrameCompleter::Async completer)
        : completer(std::move(completer)) {
      port_id = frame.port();
      frame_type = frame.frame_type();
      std::copy(std::begin(frame.data()), std::end(frame.data()), std::back_inserter(data));
      if (frame.has_meta()) {
        meta = frame.meta();
      }
    }
  };

  std::queue<ReadFrameCompleter::Async> pending_read_frame_;
  std::queue<PendingWriteRequest> pending_write_frame_;

  zx::eventpair signals_self_;
  zx::eventpair signals_peer_;
};

}  // namespace tun
}  // namespace network

#endif  // SRC_CONNECTIVITY_NETWORK_TUN_NETWORK_TUN_TUN_DEVICE_H_
