// Copyright 2022 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.

#include "udp_serde.h"

#include <fidl/fuchsia.net/cpp/wire.h>
#include <fidl/fuchsia.posix.socket/cpp/wire.h>
#include <netinet/in.h>

#include <span>

namespace fnet = fuchsia_net;

namespace {

constexpr uint8_t kMetadataSizeSegmentSize = 8;
constexpr uint8_t kMetadataSizeSize = sizeof(uint16_t);
constexpr uint8_t kMetadataSizeSegmentPaddingSize = kMetadataSizeSegmentSize - kMetadataSizeSize;
constexpr uint8_t kMetadataSizeSegmentPadding[kMetadataSizeSegmentPaddingSize] = {0};
constexpr cpp20::span<const uint8_t> kMetaSizeSegmentPaddingSpan(kMetadataSizeSegmentPadding,
                                                                 kMetadataSizeSegmentPaddingSize);

template <class T, class U, std::size_t N, std::size_t M>
void copy_into(cpp20::span<U, M>& to, const cpp20::span<T, N>& from) {
  ZX_ASSERT_MSG(from.size() <= to.size(), "from size (%zu) < to size (%zu)", from.size(),
                to.size());
  std::copy(from.begin(), from.end(), to.begin());
}

template <class T>
void advance_by(cpp20::span<T>& buf, size_t len) {
  ZX_ASSERT_MSG(buf.size() >= len, "buf size (%zu) < len (%zu)", buf.size(), len);
  buf = buf.subspan(len);
}

template <class T, class U, std::size_t N, std::size_t M>
void copy_into_and_advance_by(cpp20::span<U, M>& to, const cpp20::span<T, N>& from) {
  copy_into(to, from);
  advance_by(to, from.size());
}

uint16_t consume_meta_size_segment_unchecked(cpp20::span<uint8_t>& buf) {
  uint8_t meta_size[kMetadataSizeSize];
  cpp20::span<uint8_t, sizeof(meta_size)> meta_size_span(meta_size);
  copy_into(meta_size_span, buf.subspan(0, sizeof(meta_size)));
  advance_by(buf, kMetadataSizeSegmentSize);
  return *reinterpret_cast<uint16_t*>(meta_size);
}

void serialize_unchecked(cpp20::span<uint8_t>& buf, uint16_t meta_size,
                         const fidl::OutgoingMessage& msg) {
  copy_into_and_advance_by(
      buf, cpp20::span<uint8_t>(reinterpret_cast<uint8_t*>(&meta_size), sizeof(meta_size)));
  copy_into_and_advance_by(buf, kMetaSizeSegmentPaddingSpan);

  for (uint32_t i = 0; i < msg.iovec_actual(); ++i) {
    copy_into_and_advance_by(
        buf, cpp20::span<const uint8_t>(static_cast<const uint8_t*>(msg.iovecs()[i].buffer),
                                        msg.iovecs()[i].capacity));
  }
}

std::optional<uint16_t> compute_and_validate_message_size(const fidl::OutgoingMessage& msg) {
  size_t total = 0;
  for (uint32_t i = 0; i < msg.iovec_actual(); ++i) {
    total += msg.iovecs()[i].capacity;
  }
  // Message must fit within 2 bytes.
  if (total > std::numeric_limits<uint16_t>::max()) {
    return std::nullopt;
  }

  return static_cast<uint16_t>(total);
}

bool can_serialize_into(const cpp20::span<uint8_t>& buf, uint16_t meta_size) {
  return static_cast<uint64_t>(meta_size) + static_cast<uint64_t>(kMetadataSizeSegmentSize) <
         buf.size();
}

// Copies the address in `src_addr` into the provided SocketAddress data structures.
//
// Returns a bool indicating whether the operation succeeded:
//  - If the size of the provided `src_addr` doesn't match the size expected for an
//    IP address of the type `meta.addr_type`, returns false.
//  - Else, returns true.
template <typename Meta, size_t AllocSize>
bool copy_into_sockaddr(const Meta& meta, const cpp20::span<const uint8_t>& src_addr,
                        fidl::Arena<AllocSize>& alloc, fnet::wire::SocketAddress& dst_sockaddr,
                        fnet::wire::Ipv4SocketAddress& dst_ipv4_sockaddr,
                        fnet::wire::Ipv6SocketAddress& dst_ipv6_sockaddr) {
  switch (meta.addr_type) {
    case IpAddrType::Ipv4: {
      cpp20::span<uint8_t> dst_addr(dst_ipv4_sockaddr.address.addr.data(),
                                    sizeof(dst_ipv4_sockaddr.address.addr));
      if (src_addr.size() != dst_addr.size()) {
        return false;
      }
      copy_into(dst_addr, src_addr);
      dst_ipv4_sockaddr.port = meta.port;
      dst_sockaddr = fnet::wire::SocketAddress::WithIpv4(alloc, dst_ipv4_sockaddr);
    } break;
    case IpAddrType::Ipv6: {
      cpp20::span<uint8_t> dst_addr(dst_ipv6_sockaddr.address.addr.data(),
                                    sizeof(dst_ipv6_sockaddr.address.addr));
      if (src_addr.size() != dst_addr.size()) {
        return false;
      }
      copy_into(dst_addr, src_addr);
      dst_ipv6_sockaddr.port = meta.port;
      dst_ipv6_sockaddr.zone_index = meta.zone_index;
      dst_sockaddr = fnet::wire::SocketAddress::WithIpv6(alloc, dst_ipv6_sockaddr);
    } break;
  }
  return true;
}

template <typename T>
void copy_from_fidl_sockaddr(T& dest, const fnet::wire::SocketAddress& sockaddr) {
  dest.has_addr = true;
  switch (sockaddr.Which()) {
    case fnet::wire::SocketAddress::Tag::kIpv4: {
      const fnet::wire::Ipv4SocketAddress& ipv4 = sockaddr.ipv4();
      dest.port = ipv4.port;
      dest.addr.addr_type = IpAddrType::Ipv4;
      static_assert(sizeof(dest.addr.addr) >= sizeof(ipv4.address.addr));
      memcpy(dest.addr.addr, ipv4.address.addr.data(), sizeof(ipv4.address.addr));
      break;
    }
    case fnet::wire::SocketAddress::Tag::kIpv6: {
      const fnet::wire::Ipv6SocketAddress& ipv6 = sockaddr.ipv6();
      dest.port = ipv6.port;
      dest.addr.addr_type = IpAddrType::Ipv6;
      dest.zone_index = ipv6.zone_index;
      static_assert(sizeof(dest.addr.addr) == sizeof(ipv6.address.addr));
      memcpy(dest.addr.addr, ipv6.address.addr.data(), sizeof(ipv6.address.addr));
      break;
    }
  }
}

}  // namespace

// Size occupied by the prelude bytes in a Tx message.
const uint32_t kTxUdpPreludeSize =
    fidl::MaxSizeInChannel<fsocket::wire::SendMsgMeta, fidl::MessageDirection::kSending>() +
    kMetadataSizeSegmentSize;

// Size occupied by the prelude bytes in an Rx message.
const uint32_t kRxUdpPreludeSize =
    fidl::MaxSizeInChannel<fsocket::wire::RecvMsgMeta, fidl::MessageDirection::kSending>() +
    kMetadataSizeSegmentSize;

DeserializeSendMsgMetaResult deserialize_send_msg_meta(Buffer buf) {
  DeserializeSendMsgMetaResult res = {};
  if (buf.buf == nullptr) {
    res.err = DeserializeSendMsgMetaErrorInputBufferNull;
    return res;
  }
  if (buf.buf_size < kMetadataSizeSegmentSize) {
    res.err = DeserializeSendMsgMetaErrorInputBufferTooSmall;
    return res;
  }
  cpp20::span<uint8_t> span{buf.buf, buf.buf_size};
  uint16_t meta_size = consume_meta_size_segment_unchecked(span);
  if (span.size() < meta_size) {
    res.err = DeserializeSendMsgMetaErrorInputBufferTooSmall;
    return res;
  }
  fit::result decoded = fidl::StandaloneInplaceDecode<fsocket::wire::SendMsgMeta>(
      fidl::EncodedMessage::Create(span.subspan(0, meta_size)),
      fidl::internal::WireFormatMetadataForVersion(fidl::internal::WireFormatVersion::kV2));

  if (!decoded.is_ok()) {
    res.err = DeserializeSendMsgMetaErrorFailedToDecode;
    return res;
  }

  fsocket::wire::SendMsgMeta& meta = *decoded.value();

  if (meta.has_to()) {
    copy_from_fidl_sockaddr(res, meta.to());
  }

  if (meta.has_control()) {
    fsocket::wire::DatagramSocketSendControlData& control = meta.control();
    if (control.has_network()) {
      fsocket::wire::NetworkSocketSendControlData& network = control.network();
      if (network.has_ip()) {
        fsocket::wire::IpSendControlData& ip = network.ip();
        if (ip.has_ttl()) {
          res.cmsg_set.has_ip_ttl = true;
          res.cmsg_set.ip_ttl = ip.ttl();
        }
      }
      if (network.has_ipv6()) {
        fsocket::wire::Ipv6SendControlData& ipv6 = network.ipv6();
        if (ipv6.has_hoplimit()) {
          res.cmsg_set.has_ipv6_hoplimit = true;
          res.cmsg_set.ipv6_hoplimit = ipv6.hoplimit();
        }
        if (ipv6.has_pktinfo()) {
          res.cmsg_set.has_ipv6_pktinfo = true;
          fsocket::wire::Ipv6PktInfoSendControlData& pktinfo = ipv6.pktinfo();
          res.cmsg_set.ipv6_pktinfo.if_index = pktinfo.iface;
          static_assert(sizeof(res.cmsg_set.ipv6_pktinfo.addr) == sizeof(pktinfo.local_addr.addr));
          memcpy(res.cmsg_set.ipv6_pktinfo.addr, pktinfo.local_addr.addr.data(),
                 sizeof(pktinfo.local_addr.addr));
        }
      }
    }
  }

  res.err = DeserializeSendMsgMetaErrorNone;
  return res;
}

SerializeSendMsgMetaError serialize_send_msg_meta(fsocket::wire::SendMsgMeta& meta,
                                                  cpp20::span<uint8_t> out_buf) {
  fidl::OwnedEncodeResult encoded = fidl::StandaloneEncode(meta);
  if (!encoded.message().ok()) {
    return SerializeSendMsgMetaErrorFailedToEncode;
  }

  fidl::OutgoingMessage& outgoing_meta = encoded.message();
  std::optional meta_size_validated = compute_and_validate_message_size(outgoing_meta);
  if (!meta_size_validated.has_value() ||
      !can_serialize_into(out_buf, meta_size_validated.value())) {
    return SerializeSendMsgMetaErrorOutputBufferTooSmall;
  }
  serialize_unchecked(out_buf, meta_size_validated.value(), outgoing_meta);
  return SerializeSendMsgMetaErrorNone;
}

SerializeSendMsgMetaError serialize_send_msg_meta(const SendMsgMeta* meta_, ConstBuffer addr,
                                                  Buffer out_buf) {
  fidl::Arena<
      fidl::MaxSizeInChannel<fsocket::wire::SendMsgMeta, fidl::MessageDirection::kSending>()>
      alloc;
  fidl::WireTableBuilder<fsocket::wire::SendMsgMeta> meta_builder =
      fsocket::wire::SendMsgMeta::Builder(alloc);

  if (addr.buf == nullptr) {
    return SerializeSendMsgMetaErrorAddrBufferNull;
  }
  fnet::wire::SocketAddress socket_addr;
  fnet::wire::Ipv4SocketAddress ipv4_socket_addr;
  fnet::wire::Ipv6SocketAddress ipv6_socket_addr;
  const SendMsgMeta& meta = *meta_;
  if (!copy_into_sockaddr(meta, cpp20::span<const uint8_t>(addr.buf, addr.buf_size), alloc,
                          socket_addr, ipv4_socket_addr, ipv6_socket_addr)) {
    return SerializeSendMsgMetaErrorAddrBufferSizeMismatch;
  }
  meta_builder.to(socket_addr);

  const SendAndRecvCmsgSet& cmsg_set = meta.cmsg_set;
  fidl::WireTableBuilder<fsocket::wire::NetworkSocketSendControlData> net_control_builder =
      fsocket::wire::NetworkSocketSendControlData::Builder(alloc);
  bool net_control_set = false;

  {
    fidl::WireTableBuilder<fsocket::wire::IpSendControlData> ip_control_builder =
        fsocket::wire::IpSendControlData::Builder(alloc);
    bool ip_control_set = false;
    if (cmsg_set.has_ip_ttl) {
      ip_control_set = true;
      ip_control_builder.ttl(cmsg_set.ip_ttl);
    }
    if (ip_control_set) {
      net_control_set = true;
      net_control_builder.ip(ip_control_builder.Build());
    }
  }

  {
    fidl::WireTableBuilder<fsocket::wire::Ipv6SendControlData> ipv6_control_builder =
        fsocket::wire::Ipv6SendControlData::Builder(alloc);
    bool ipv6_control_set = false;
    if (cmsg_set.has_ipv6_pktinfo) {
      const Ipv6PktInfo& pktinfo = cmsg_set.ipv6_pktinfo;
      fuchsia_posix_socket::wire::Ipv6PktInfoSendControlData fidl_pktinfo = {
          .iface = pktinfo.if_index,
      };
      static_assert(sizeof(pktinfo.addr) == sizeof(fidl_pktinfo.local_addr.addr));
      memcpy(fidl_pktinfo.local_addr.addr.data(), pktinfo.addr,
             sizeof(fidl_pktinfo.local_addr.addr));
      ipv6_control_set = true;
      ipv6_control_builder.pktinfo(fidl_pktinfo);
    }
    if (cmsg_set.has_ipv6_hoplimit) {
      ipv6_control_set = true;
      ipv6_control_builder.hoplimit(cmsg_set.ipv6_hoplimit);
    }
    if (ipv6_control_set) {
      net_control_set = true;
      net_control_builder.ipv6(ipv6_control_builder.Build());
    }
  }

  if (net_control_set) {
    fidl::WireTableBuilder<fsocket::wire::DatagramSocketSendControlData> datagram_control_builder =
        fsocket::wire::DatagramSocketSendControlData::Builder(alloc);
    datagram_control_builder.network(net_control_builder.Build());
    meta_builder.control(datagram_control_builder.Build());
  }

  fsocket::wire::SendMsgMeta fidl_meta = meta_builder.Build();
  if (out_buf.buf == nullptr) {
    return SerializeSendMsgMetaErrorOutputBufferNull;
  }
  return serialize_send_msg_meta(fidl_meta, cpp20::span<uint8_t>(out_buf.buf, out_buf.buf_size));
}

DeserializeRecvMsgMetaResult deserialize_recv_msg_meta(Buffer buf) {
  DeserializeRecvMsgMetaResult res = {};
  if (buf.buf == nullptr) {
    res.err = DeserializeRecvMsgMetaErrorInputBufferNull;
    return res;
  }
  fit::result decoded_meta = deserialize_recv_msg_meta(cpp20::span<uint8_t>(buf.buf, buf.buf_size));
  if (!decoded_meta.is_ok()) {
    res.err = DeserializeRecvMsgMetaErrorUnspecifiedDecodingFailure;
    return res;
  }
  const fuchsia_posix_socket::wire::RecvMsgMeta& meta = *decoded_meta.value();
  if (meta.has_from()) {
    copy_from_fidl_sockaddr(res, meta.from());
  }

  if (meta.has_payload_len()) {
    res.payload_size = meta.payload_len();
  }

  if (meta.has_control()) {
    const fsocket::wire::DatagramSocketRecvControlData& control = meta.control();
    if (control.has_network()) {
      const fsocket::wire::NetworkSocketRecvControlData& network = control.network();
      if (network.has_socket()) {
        const fsocket::wire::SocketRecvControlData& socket = network.socket();
        if (socket.has_timestamp()) {
          const fsocket::wire::Timestamp& timestamp = socket.timestamp();
          res.cmsg_set.has_timestamp_nanos = true;
          res.cmsg_set.timestamp_nanos = timestamp.nanoseconds;
        }
      }
      if (network.has_ip()) {
        const fsocket::wire::IpRecvControlData& ip = network.ip();
        if (ip.has_ttl()) {
          res.cmsg_set.send_and_recv.has_ip_ttl = true;
          res.cmsg_set.send_and_recv.ip_ttl = ip.ttl();
        }
        if (ip.has_tos()) {
          res.cmsg_set.has_ip_tos = true;
          res.cmsg_set.ip_tos = ip.tos();
        }
      }
      if (network.has_ipv6()) {
        const fsocket::wire::Ipv6RecvControlData& ipv6 = network.ipv6();
        if (ipv6.has_hoplimit()) {
          res.cmsg_set.send_and_recv.has_ipv6_hoplimit = true;
          res.cmsg_set.send_and_recv.ipv6_hoplimit = ipv6.hoplimit();
        }
        if (ipv6.has_pktinfo()) {
          res.cmsg_set.send_and_recv.has_ipv6_pktinfo = true;
          const fsocket::wire::Ipv6PktInfoRecvControlData& pktinfo = ipv6.pktinfo();
          res.cmsg_set.send_and_recv.ipv6_pktinfo.if_index = pktinfo.iface;
          static_assert(sizeof(res.cmsg_set.send_and_recv.ipv6_pktinfo.addr) ==
                        sizeof(pktinfo.header_destination_addr.addr));
          memcpy(res.cmsg_set.send_and_recv.ipv6_pktinfo.addr,
                 pktinfo.header_destination_addr.addr.data(),
                 sizeof(pktinfo.header_destination_addr.addr));
        }
        if (ipv6.has_tclass()) {
          res.cmsg_set.has_ipv6_tclass = true;
          res.cmsg_set.ipv6_tclass = ipv6.tclass();
        }
      }
    }
  }
  return res;
}

fit::result<fidl::Error, fidl::DecodedValue<fsocket::wire::RecvMsgMeta>> deserialize_recv_msg_meta(
    cpp20::span<uint8_t> buf) {
  if (buf.size() < kMetadataSizeSegmentSize) {
    return fit::error(fidl::Error::DecodeError(ZX_ERR_BUFFER_TOO_SMALL));
  }
  uint16_t meta_size = consume_meta_size_segment_unchecked(buf);
  if (meta_size > buf.size()) {
    return fit::error(fidl::Error::DecodeError(ZX_ERR_BUFFER_TOO_SMALL));
  }

  return fidl::StandaloneInplaceDecode<fsocket::wire::RecvMsgMeta>(
      fidl::EncodedMessage::Create(buf.subspan(0, meta_size)),
      fidl::internal::WireFormatMetadataForVersion(fidl::internal::WireFormatVersion::kV2));
}

SerializeRecvMsgMetaError serialize_recv_msg_meta(const RecvMsgMeta* meta_, ConstBuffer addr,
                                                  Buffer out_buf) {
  fidl::Arena<
      fidl::MaxSizeInChannel<fsocket::wire::RecvMsgMeta, fidl::MessageDirection::kSending>()>
      alloc;
  fidl::WireTableBuilder<fsocket::wire::RecvMsgMeta> meta_builder =
      fsocket::wire::RecvMsgMeta::Builder(alloc);

  if (addr.buf == nullptr) {
    return SerializeRecvMsgMetaErrorFromAddrBufferNull;
  }
  fnet::wire::SocketAddress socket_addr;
  fnet::wire::Ipv4SocketAddress ipv4_socket_addr;
  fnet::wire::Ipv6SocketAddress ipv6_socket_addr;
  const RecvMsgMeta& meta = *meta_;
  if (!copy_into_sockaddr(meta, cpp20::span<const uint8_t>(addr.buf, addr.buf_size), alloc,
                          socket_addr, ipv4_socket_addr, ipv6_socket_addr)) {
    return SerializeRecvMsgMetaErrorFromAddrBufferTooSmall;
  }
  meta_builder.from(socket_addr);

  fidl::WireTableBuilder<fsocket::wire::NetworkSocketRecvControlData> net_control_builder =
      fsocket::wire::NetworkSocketRecvControlData::Builder(alloc);
  bool net_control_set = false;

  {
    fidl::WireTableBuilder<fsocket::wire::IpRecvControlData> ip_control_builder =
        fsocket::wire::IpRecvControlData::Builder(alloc);
    bool ip_control_set = false;
    if (meta.cmsg_set.has_ip_tos) {
      ip_control_set = true;
      ip_control_builder.tos(meta.cmsg_set.ip_tos);
    }
    if (meta.cmsg_set.send_and_recv.has_ip_ttl) {
      ip_control_set = true;
      ip_control_builder.ttl(meta.cmsg_set.send_and_recv.ip_ttl);
    }
    if (ip_control_set) {
      net_control_set = true;
      net_control_builder.ip(ip_control_builder.Build());
    }
  }

  {
    fidl::WireTableBuilder<fsocket::wire::Ipv6RecvControlData> ipv6_control_builder =
        fsocket::wire::Ipv6RecvControlData::Builder(alloc);
    bool ipv6_control_set = false;
    if (meta.cmsg_set.send_and_recv.has_ipv6_pktinfo) {
      const Ipv6PktInfo& pktinfo = meta.cmsg_set.send_and_recv.ipv6_pktinfo;
      fuchsia_posix_socket::wire::Ipv6PktInfoRecvControlData fidl_pktinfo = {
          .iface = pktinfo.if_index,
      };
      const cpp20::span<const uint8_t> src(pktinfo.addr);
      cpp20::span<uint8_t> dst(fidl_pktinfo.header_destination_addr.addr.data(),
                               decltype(fidl_pktinfo.header_destination_addr.addr)::size());
      copy_into(dst, src);
      ipv6_control_set = true;
      ipv6_control_builder.pktinfo(fidl_pktinfo);
    }
    if (meta.cmsg_set.send_and_recv.has_ipv6_hoplimit) {
      ipv6_control_set = true;
      ipv6_control_builder.hoplimit(meta.cmsg_set.send_and_recv.ipv6_hoplimit);
    }
    if (meta.cmsg_set.has_ipv6_tclass) {
      ipv6_control_set = true;
      ipv6_control_builder.tclass(meta.cmsg_set.ipv6_tclass);
    }
    if (ipv6_control_set) {
      net_control_set = true;
      net_control_builder.ipv6(ipv6_control_builder.Build());
    }
  }

  {
    fidl::WireTableBuilder<fsocket::wire::SocketRecvControlData> sock_control_builder =
        fsocket::wire::SocketRecvControlData::Builder(alloc);
    bool sock_control_set = false;
    if (meta.cmsg_set.has_timestamp_nanos) {
      sock_control_set = true;
      sock_control_builder.timestamp(fsocket::wire::Timestamp{
          .nanoseconds = meta.cmsg_set.timestamp_nanos,
      });
    }
    if (sock_control_set) {
      net_control_set = true;
      net_control_builder.socket(sock_control_builder.Build());
    }
  }

  if (net_control_set) {
    fidl::WireTableBuilder<fsocket::wire::DatagramSocketRecvControlData> datagram_control_builder =
        fsocket::wire::DatagramSocketRecvControlData::Builder(alloc);
    datagram_control_builder.network(net_control_builder.Build());
    meta_builder.control(datagram_control_builder.Build());
  }

  meta_builder.payload_len(meta.payload_size);

  fsocket::wire::RecvMsgMeta fsocket_meta = meta_builder.Build();

  fidl::OwnedEncodeResult encoded = fidl::StandaloneEncode(fsocket_meta);
  if (!encoded.message().ok()) {
    return SerializeRecvMsgMetaErrorFailedToEncode;
  }

  if (out_buf.buf == nullptr) {
    return SerializeRecvMsgMetaErrorOutputBufferNull;
  }

  cpp20::span<uint8_t> outbuf{out_buf.buf, out_buf.buf_size};

  fidl::OutgoingMessage& outgoing_meta = encoded.message();
  std::optional meta_size_validated = compute_and_validate_message_size(outgoing_meta);
  if (!meta_size_validated.has_value() ||
      !can_serialize_into(outbuf, meta_size_validated.value())) {
    return SerializeRecvMsgMetaErrorOutputBufferTooSmall;
  }
  serialize_unchecked(outbuf, meta_size_validated.value(), outgoing_meta);
  return SerializeRecvMsgMetaErrorNone;
}
