// Copyright 2016 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 GARNET_BIN_NETCONNECTOR_MESSAGE_TRANSCEIVER_H_
#define GARNET_BIN_NETCONNECTOR_MESSAGE_TRANSCEIVER_H_

#include <queue>
#include <vector>

#include <lib/async/dispatcher.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>

#include "lib/fsl/tasks/fd_waiter.h"
#include "src/lib/files/unique_fd.h"
#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "lib/netconnector/cpp/message_relay.h"

namespace netconnector {

/*

All packets conform to the following format:

    sentinel     (1 byte, 0xcc)
    type         (1 byte)
    channel      (2 bytes, 0x0000)
    payload size (4 bytes)
    payload      (<payload size> bytes)

The sentinel is just a sanity check, and the channel isn't used (always zeros).
All integers are in big-endian order.

Here are the types:

    version        (0x00) indicates the version of the sender
    service name   (0x01) indicates the name of the desired service
    message        (0x02) contains a message

A version packet has a 4-byte payload specifying the version of the sender.
Version packets are sent by both sides upon connection establishment. The format
of subsequent traffic on the connection must conform to the minimum of the two
version numbers. If either party isn't backward-compatible to that version, it
must close the connection.

A service name packet's payload consists of a string identifying the desired
service. The requestor sends a service name packet after the version packets
are exchanged. If the remote party doesn't recognize the service name,
it must close the connection.

A message packet contains a message intended for the requestor/service.

If either party receives a malformed packet, it must close the connection.

*/

// Abstract base class that shuttles data-only messages between a channel and
// a TCP socket.
//
// MessageTransceiver is not thread-safe. All methods calls must be serialized.
// All overridables will be called on the same thread on which the transceiver
// was constructed.
class MessageTransceiver {
 public:
  virtual ~MessageTransceiver();

 protected:
  MessageTransceiver(fxl::UniqueFD socket_fd);

  // Sets the channel that the transceiver should use to forward messages.
  void SetChannel(zx::channel channel);

  // Sends a service name.
  void SendServiceName(const std::string& service_name);

  // Sends a message.
  void SendMessage(std::vector<uint8_t> message);

  // Closes the connection.
  void CloseConnection();

  // Called when a version is received.
  virtual void OnVersionReceived(uint32_t version) = 0;

  // Called when a service name is received.
  virtual void OnServiceNameReceived(const std::string& service_name) = 0;

  // Called when a message is received. The default implementation puts the
  // message on the channel supplied by SetChannel.
  virtual void OnMessageReceived(std::vector<uint8_t> message);

  // Called when the connection closes. The default implementation does nothing.
  virtual void OnConnectionClosed();

 private:
  enum class PacketType : uint8_t {
    kVersion = 0,
    kServiceName = 1,
    kMessage = 2,
    kMax = 2
  };

  struct __attribute__((packed)) PacketHeader {
    uint8_t sentinel_;
    PacketType type_;
    uint16_t channel_;
    uint32_t payload_size_;
  };

  static const size_t kRecvBufferSize = 2048;
  static const uint8_t kSentinel = 0xcc;
  // TODO(dalesat): Make this larger when zx::channel messages can be larger.
  static const uint32_t kMaxPayloadSize = 65536;
  static const uint32_t kVersion = 1;
  static const uint32_t kNullVersion = 0;
  static const uint32_t kMinSupportedVersion = 1;
  static const size_t kMaxServiceNameLength = 1024;

  // Sends a version packet.
  void SendVersionPacket();

  // Queues up a task that calls |SendPacket| to be run when the socket is
  // ready.
  void PostSendTask(fit::closure task);

  // Waits (using |fd_send_waiter_|) for the socket to be ready to send if there
  // are send tasks pending.
  void MaybeWaitToSend();

  // Sends a packet. Must be called in the send thread.
  void SendPacket(PacketType type, const void* payload, size_t payload_size);

  // Waits (using |fd_recv_waiter_|) for an inbound message.
  void WaitToReceive();

  // Receives a message.
  void ReceiveMessage();

  // Parses |byte_count| received bytes from |receive_buffer_|.
  void ParseReceivedBytes(size_t byte_count);

  // Called when a complete packet has been received.
  void OnReceivedPacketComplete();

  // Cancels any waiters that are currently waiting.
  void CancelWaiters();

  // Copies received bytes.
  // |*bytes| points to the received bytes and is increased to reflect the
  //     number of bytes actually copied.
  // |*byte_count| indicates the number of bytes available to copy and is
  //     decreased to reflect the number of bytes actually copied.
  // |dest| is the destination buffer.
  // |dest_size| is the size of the destination buffer.
  // |dest_packet_offset| indicates where dest occurs logically in the packet.
  // Returns true if and only if dest is filled to its end.
  // |receive_packet_offset_| indicates where we are in the packet and must be
  // at least |dest_packet_offset| and less than the sum of |dest_packet_offset|
  // and |dest_size|. |receive_packet_offset_| is also increased to reflect the
  // number of bytes actually copied.
  bool CopyReceivedBytes(uint8_t** bytes, size_t* byte_count, uint8_t* dest,
                         size_t dest_size, size_t dest_packet_offset);

  // Parses a uint32 out of receive_buffer_.
  uint32_t ParsePayloadUint32();

  // Parses string out of receive_buffer_.
  std::string ParsePayloadString();

  fxl::UniqueFD socket_fd_;
  async_dispatcher_t* dispatcher_;
  zx::channel channel_;
  MessageRelay message_relay_;

  uint32_t version_ = kNullVersion;

  fsl::FDWaiter fd_recv_waiter_;
  bool fd_recv_waiter_waiting_ = false;
  std::vector<uint8_t> receive_buffer_;
  size_t receive_packet_offset_ = 0;
  PacketHeader receive_packet_header_;
  std::vector<uint8_t> receive_packet_payload_;

  // In general, |fd_send_waiter_| is waiting if and only if |send_tasks_| isn't
  // empty. The only exception to this is in the code that actually does the
  // sending (the waiter callback, |SendPacket| and the send tasks).
  fsl::FDWaiter fd_send_waiter_;
  std::queue<fit::closure> send_tasks_;

  FXL_DISALLOW_COPY_AND_ASSIGN(MessageTransceiver);
};

}  // namespace netconnector

#endif  // GARNET_BIN_NETCONNECTOR_MESSAGE_TRANSCEIVER_H_
