// 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_VIRTUALIZATION_TESTS_FAKE_NETSTACK_H_
#define SRC_VIRTUALIZATION_TESTS_FAKE_NETSTACK_H_

#include <fuchsia/netstack/cpp/fidl_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/wait.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fit/bridge.h>
#include <zircon/device/ethernet.h>

#include <map>
#include <vector>

class Device {
 public:
  static zx_status_t Create(fuchsia::hardware::ethernet::DeviceSyncPtr eth_device,
                            std::unique_ptr<Device>* out);

  zx_status_t Start(async_dispatcher_t* dispatcher);

  fit::promise<std::vector<uint8_t>, zx_status_t> ReadPacket();
  fit::promise<void, zx_status_t> WritePacket(std::vector<uint8_t> packet);

 private:
  Device(fuchsia::hardware::ethernet::DeviceSyncPtr eth_device, zx::fifo rx, zx::fifo tx,
         zx::vmo vmo, uintptr_t io_addr)
      : eth_device_(std::move(eth_device)),
        rx_(std::move(rx)),
        tx_(std::move(tx)),
        vmo_(std::move(vmo)),
        io_addr_(io_addr) {
    rx_wait_.set_trigger(ZX_FIFO_READABLE | ZX_FIFO_PEER_CLOSED);
    rx_wait_.set_object(rx_.get());

    tx_wait_.set_trigger(ZX_FIFO_READABLE | ZX_FIFO_PEER_CLOSED);
    tx_wait_.set_object(tx_.get());
  }

  void OnReceive(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                 const zx_packet_signal_t* signal);
  void OnTransmit(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                  const zx_packet_signal_t* signal);

  fit::promise<eth_fifo_entry_t, zx_status_t> GetRxEntry();
  fit::promise<eth_fifo_entry_t, zx_status_t> GetTxEntry();

  fuchsia::hardware::ethernet::DeviceSyncPtr eth_device_;
  zx::fifo rx_;
  zx::fifo tx_;
  zx::vmo vmo_;
  const uintptr_t io_addr_;

  std::mutex mutex_;
  std::vector<fit::completer<eth_fifo_entry_t, zx_status_t>> rx_completers_ __TA_GUARDED(mutex_);
  std::vector<fit::completer<eth_fifo_entry_t, zx_status_t>> tx_completers_ __TA_GUARDED(mutex_);
  async::WaitMethod<Device, &Device::OnReceive> rx_wait_{this};
  async::WaitMethod<Device, &Device::OnTransmit> tx_wait_{this};
};

class FakeNetstack : public fuchsia::netstack::testing::Netstack_TestBase {
 public:
  FakeNetstack() {
    // Start a thread for the Device waiters. We can't use the main test thread, because it will
    // block to run test utils and deadlock the test.
    loop_.StartThread("FakeNetstack");
  }

  ~FakeNetstack() {
    loop_.Quit();
    loop_.JoinThreads();
    loop_.Shutdown();
  }

  void NotImplemented_(const std::string& name) override {}

  // fuchsia::netstack::testing::Netstack_TestBase
  void GetInterfaces(GetInterfacesCallback callback) override;
  void BridgeInterfaces(std::vector<uint32_t> nicids, BridgeInterfacesCallback callback) override;
  void AddEthernetDevice(std::string topological_path,
                         fuchsia::netstack::InterfaceConfig interfaceConfig,
                         ::fidl::InterfaceHandle<::fuchsia::hardware::ethernet::Device> device,
                         AddEthernetDeviceCallback callback) override;

  fidl::InterfaceRequestHandler<fuchsia::netstack::Netstack> GetHandler() {
    return bindings_.GetHandler(this);
  }

  // Send a packet with UDP headers, including the ethernet and IPv6 headers, to the interface with
  // the specified MAC address.
  fit::promise<void, zx_status_t> SendUdpPacket(
      const fuchsia::hardware::ethernet::MacAddress& mac_addr, std::vector<uint8_t> packet);

  // Send a raw packet to the interface with the specified MAC address.
  fit::promise<void, zx_status_t> SendPacket(
      const fuchsia::hardware::ethernet::MacAddress& mac_addr, std::vector<uint8_t> packet);

  // Receive a raw packet from the interface with the specified MAC address.
  fit::promise<std::vector<uint8_t>, zx_status_t> ReceivePacket(
      const fuchsia::hardware::ethernet::MacAddress& mac_addr);

 private:
  struct CompareMacAddress {
    bool operator()(const fuchsia::hardware::ethernet::MacAddress& a,
                    const fuchsia::hardware::ethernet::MacAddress& b) const {
      // The octets of a MacAddress are a std::array, which implements lexigraphical ordering.
      return a.octets < b.octets;
    }
  };

  fit::promise<Device*> GetDevice(const fuchsia::hardware::ethernet::MacAddress& mac_addr);

  fidl::BindingSet<fuchsia::netstack::Netstack> bindings_;
  std::mutex mutex_;
  // Maps MAC addresses to devices.
  std::map<fuchsia::hardware::ethernet::MacAddress, std::unique_ptr<Device>, CompareMacAddress>
      devices_ __TA_GUARDED(mutex_);
  // Maps MAC addresses to completers, to enable the GetDevice promises.
  std::map<fuchsia::hardware::ethernet::MacAddress, std::vector<fit::completer<Device*>>,
           CompareMacAddress>
      completers_ __TA_GUARDED(mutex_);

  async::Loop loop_{&kAsyncLoopConfigNoAttachToCurrentThread};

  uint8_t nic_counter_ = 1;
};

#endif  // SRC_VIRTUALIZATION_TESTS_FAKE_NETSTACK_H_
