// Copyright 2018 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 <fidl/fuchsia.net.name/cpp/wire.h>
#include <fidl/fuchsia.net/cpp/wire.h>
#include <fidl/fuchsia.posix.socket.packet/cpp/wire.h>
#include <fidl/fuchsia.posix.socket.raw/cpp/wire.h>
#include <ifaddrs.h>
#include <lib/zx/channel.h>
#include <lib/zx/eventpair.h>
#include <lib/zxio/bsdsocket.h>
#include <lib/zxio/ops.h>
#include <lib/zxio/types.h>
#include <lib/zxio/watcher.h>
#include <lib/zxio/zxio.h>
#include <string.h>
#include <zircon/syscalls.h>

#include <atomic>
#include <new>
#include <type_traits>

#include <netpacket/packet.h>

#include "private.h"

namespace fsocket = fuchsia_posix_socket;
namespace frawsocket = fuchsia_posix_socket_raw;
namespace fpacketsocket = fuchsia_posix_socket_packet;

// The private fields of a |zxio_t| object.
//
// In |ops.h|, the |zxio_t| struct is defined as opaque. Clients of the zxio
// library are forbidden from relying upon the structure of |zxio_t| objects.
// To avoid temptation, the details of the structure are defined only in this
// implementation file and are not visible in the header.
using zxio_internal_t = struct zxio_internal {
  explicit zxio_internal(const zxio_ops_t* ops) : ops(ops) {}

  const zxio_ops_t* ops;

  // When adding fields to the |zxio_internal_t| struct, one may take from
  // the reserved bytes here to ensure that the ABI stays compatible.
  uint64_t reserved[3];
};

static_assert(sizeof(zxio_t) == sizeof(zxio_internal_t), "zxio_t should match zxio_internal_t");

// Converters from the public (opaque) types to the internal (implementation) types.
namespace {

zxio_internal_t* to_internal(zxio_t* io) { return reinterpret_cast<zxio_internal_t*>(io); }

const zxio_internal_t* to_internal(const zxio_t* io) {
  return reinterpret_cast<const zxio_internal_t*>(io);
}

}  // namespace

bool zxio_is_valid(const zxio_t* io) {
  if (io == nullptr) {
    return false;
  }
  const zxio_internal_t* zio = to_internal(io);
  return zio->ops != nullptr;
}

void zxio_init(zxio_t* io, const zxio_ops_t* ops) { new (io) zxio_internal_t(ops); }

const zxio_ops_t* zxio_get_ops(zxio_t* io) {
  const zxio_internal_t* zio = to_internal(io);
  return zio->ops;
}

zx_status_t zxio_close(zxio_t* io, const bool should_wait) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  static_assert(std::is_trivially_destructible<zxio_internal_t>::value,
                "zxio_internal_t must have trivial destructor");
  zxio_internal_t* zio = to_internal(io);
  zx_status_t status = zio->ops->close(io, should_wait);
  // Poison the object. Double destruction is undefined behavior.
  zio->ops = nullptr;
  return status;
}

zx_status_t zxio_release(zxio_t* io, zx_handle_t* out_handle) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->release(io, out_handle);
}

zx_status_t zxio_borrow(zxio_t* io, zx_handle_t* out_handle) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->borrow(io, out_handle);
}

zx_status_t zxio_clone(zxio_t* io, zx_handle_t* out_handle) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->clone(io, out_handle);
}

zx_status_t zxio_wait_one(zxio_t* io, zxio_signals_t signals, zx_time_t deadline,
                          zxio_signals_t* out_observed) {
  if (!zxio_is_valid(io)) {
    *out_observed = ZXIO_SIGNAL_NONE;
    return ZX_ERR_BAD_HANDLE;
  }
  zx_handle_t handle = ZX_HANDLE_INVALID;
  zx_signals_t zx_signals = ZX_SIGNAL_NONE;
  zxio_wait_begin(io, signals, &handle, &zx_signals);
  if (handle == ZX_HANDLE_INVALID) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_signals_t zx_observed = ZX_SIGNAL_NONE;
  zx_status_t status = zx_object_wait_one(handle, zx_signals, deadline, &zx_observed);
  if (status != ZX_OK) {
    return status;
  }
  zxio_wait_end(io, zx_signals, out_observed);
  return ZX_OK;
}

void zxio_wait_begin(zxio_t* io, zxio_signals_t zxio_signals, zx_handle_t* out_handle,
                     zx_signals_t* out_zx_signals) {
  if (!zxio_is_valid(io)) {
    *out_handle = ZX_HANDLE_INVALID;
    *out_zx_signals = ZX_SIGNAL_NONE;
    return;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->wait_begin(io, zxio_signals, out_handle, out_zx_signals);
}

void zxio_wait_end(zxio_t* io, zx_signals_t zx_signals, zxio_signals_t* out_zxio_signals) {
  if (!zxio_is_valid(io)) {
    *out_zxio_signals = ZXIO_SIGNAL_NONE;
    return;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->wait_end(io, zx_signals, out_zxio_signals);
}

zx_status_t zxio_sync(zxio_t* io) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->sync(io);
}

zx_status_t zxio_attr_get(zxio_t* io, zxio_node_attributes_t* inout_attr) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (inout_attr->has.fsverity_root_hash && inout_attr->fsverity_root_hash == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->attr_get(io, inout_attr);
}

zx_status_t zxio_attr_set(zxio_t* io, const zxio_node_attributes_t* attr) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->attr_set(io, attr);
}

zx_status_t zxio_enable_verity(zxio_t* io, const zxio_fsverity_descriptor_t* descriptor) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->enable_verity(io, descriptor);
}

zx_status_t zxio_read(zxio_t* io, void* buffer, size_t capacity, zxio_flags_t flags,
                      size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = buffer,
      .capacity = capacity,
  };
  return zxio_readv(io, &vector, 1, flags, out_actual);
}

zx_status_t zxio_read_at(zxio_t* io, zx_off_t offset, void* buffer, size_t capacity,
                         zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = buffer,
      .capacity = capacity,
  };
  return zxio_readv_at(io, offset, &vector, 1, flags, out_actual);
}

zx_status_t zxio_write(zxio_t* io, const void* buffer, size_t capacity, zxio_flags_t flags,
                       size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = const_cast<void*>(buffer),
      .capacity = capacity,
  };
  return zxio_writev(io, &vector, 1, flags, out_actual);
}

zx_status_t zxio_write_at(zxio_t* io, zx_off_t offset, const void* buffer, size_t capacity,
                          zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = const_cast<void*>(buffer),
      .capacity = capacity,
  };
  return zxio_writev_at(io, offset, &vector, 1, flags, out_actual);
}

zx_status_t zxio_readv(zxio_t* io, const zx_iovec_t* vector, size_t vector_count,
                       zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->readv(io, vector, vector_count, flags, out_actual);
}

zx_status_t zxio_readv_at(zxio_t* io, zx_off_t offset, const zx_iovec_t* vector,
                          size_t vector_count, zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->readv_at(io, offset, vector, vector_count, flags, out_actual);
}

zx_status_t zxio_writev(zxio_t* io, const zx_iovec_t* vector, size_t vector_count,
                        zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->writev(io, vector, vector_count, flags, out_actual);
}

zx_status_t zxio_writev_at(zxio_t* io, zx_off_t offset, const zx_iovec_t* vector,
                           size_t vector_count, zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->writev_at(io, offset, vector, vector_count, flags, out_actual);
}

static_assert(ZX_STREAM_SEEK_ORIGIN_START == ZXIO_SEEK_ORIGIN_START, "ZXIO should match ZX");
static_assert(ZX_STREAM_SEEK_ORIGIN_CURRENT == ZXIO_SEEK_ORIGIN_CURRENT, "ZXIO should match ZX");
static_assert(ZX_STREAM_SEEK_ORIGIN_END == ZXIO_SEEK_ORIGIN_END, "ZXIO should match ZX");

zx_status_t zxio_seek(zxio_t* io, zxio_seek_origin_t start, int64_t offset, size_t* out_offset) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->seek(io, start, offset, out_offset);
}

zx_status_t zxio_truncate(zxio_t* io, uint64_t length) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->truncate(io, length);
}

zx_status_t zxio_flags_get(zxio_t* io, uint32_t* out_flags) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->flags_get(io, out_flags);
}

zx_status_t zxio_flags_set(zxio_t* io, uint32_t flags) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->flags_set(io, flags);
}

zx_status_t zxio_token_get(zxio_t* io, zx_handle_t* out_token) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->token_get(io, out_token);
}

zx_status_t zxio_vmo_get(zxio_t* io, zxio_vmo_flags_t flags, zx_handle_t* out_vmo) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->vmo_get(io, flags, out_vmo);
}

zx_status_t zxio_on_mapped(zxio_t* io, void* ptr) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->on_mapped(io, ptr);
}

zx_status_t zxio_get_read_buffer_available(zxio_t* io, size_t* out_available) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->get_read_buffer_available(io, out_available);
}

zx_status_t zxio_shutdown(zxio_t* io, zxio_shutdown_options_t options, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->shutdown(io, options, out_code);
}

zx_status_t zxio_open(zxio_t* directory, uint32_t flags, const char* path, size_t path_len,
                      zxio_storage_t* storage) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->open(directory, flags, path, path_len, storage);
}

zx_status_t zxio_open2(zxio_t* directory, const char* path, size_t path_len,
                       const zxio_open_options_t* options, zxio_node_attributes_t* inout_attr,
                       zxio_storage_t* storage) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->open2(directory, path, path_len, options, inout_attr, storage);
}

zx_status_t zxio_open_async(zxio_t* directory, uint32_t flags, const char* path, size_t path_len,
                            zx_handle_t request) {
  if (!zxio_is_valid(directory)) {
    zx_handle_close(request);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->open_async(directory, flags, path, path_len, request);
}

zx_status_t zxio_unlink(zxio_t* directory, const char* name, size_t name_len, int flags) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->unlink(directory, name, name_len, flags);
}

zx_status_t zxio_rename(zxio_t* old_directory, const char* old_path, size_t old_path_len,
                        zx_handle_t new_directory_token, const char* new_path,
                        size_t new_path_len) {
  if (!zxio_is_valid(old_directory)) {
    zx_handle_close(new_directory_token);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(old_directory);
  return zio->ops->rename(old_directory, old_path, old_path_len, new_directory_token, new_path,
                          new_path_len);
}

zx_status_t zxio_link(zxio_t* src_directory, const char* src_path, size_t src_path_len,
                      zx_handle_t dst_directory_token, const char* dst_path, size_t dst_path_len) {
  if (!zxio_is_valid(src_directory)) {
    zx_handle_close(dst_directory_token);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(src_directory);
  return zio->ops->link(src_directory, src_path, src_path_len, dst_directory_token, dst_path,
                        dst_path_len);
}

zx_status_t zxio_link_into(zxio_t* object, zx_handle_t dst_directory_token, const char* dst_path,
                           size_t dst_path_len) {
  if (!zxio_is_valid(object)) {
    zx_handle_close(dst_directory_token);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(object);
  return zio->ops->link_into(object, dst_directory_token, dst_path, dst_path_len);
}

zx_status_t zxio_dirent_iterator_init(zxio_dirent_iterator_t* iterator, zxio_t* directory) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (iterator == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->dirent_iterator_init(directory, iterator);
}

zx_status_t zxio_dirent_iterator_next(zxio_dirent_iterator_t* iterator,
                                      zxio_dirent_t* inout_entry) {
  if (!zxio_is_valid(iterator->io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (inout_entry == nullptr || inout_entry->name == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(iterator->io);
  return zio->ops->dirent_iterator_next(iterator->io, iterator, inout_entry);
}

zx_status_t zxio_dirent_iterator_rewind(zxio_dirent_iterator_t* iterator) {
  if (!zxio_is_valid(iterator->io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(iterator->io);
  return zio->ops->dirent_iterator_rewind(iterator->io, iterator);
}

void zxio_dirent_iterator_destroy(zxio_dirent_iterator_t* iterator) {
  if (!zxio_is_valid(iterator->io)) {
    return;
  }
  zxio_internal_t* zio = to_internal(iterator->io);
  zio->ops->dirent_iterator_destroy(iterator->io, iterator);
}

zx_status_t zxio_isatty(zxio_t* io, bool* tty) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->isatty(io, tty);
}

zx_status_t zxio_get_window_size(zxio_t* io, uint32_t* width, uint32_t* height) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (width == nullptr || height == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->get_window_size(io, width, height);
}

zx_status_t zxio_set_window_size(zxio_t* io, uint32_t width, uint32_t height) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->set_window_size(io, width, height);
}

zx_status_t zxio_ioctl(zxio_t* io, int request, int16_t* out_code, va_list va) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->ioctl(io, request, out_code, va);
}

zx_status_t zxio_watch_directory(zxio_t* directory, zxio_watch_directory_cb cb, zx_time_t deadline,
                                 void* context) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->watch_directory(directory, cb, deadline, context);
}

zx_status_t zxio_bind(zxio_t* io, const struct sockaddr* addr, socklen_t addrlen,
                      int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->bind(io, addr, addrlen, out_code);
}

zx_status_t zxio_connect(zxio_t* io, const struct sockaddr* addr, socklen_t addrlen,
                         int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->connect(io, addr, addrlen, out_code);
}

zx_status_t zxio_listen(zxio_t* io, int backlog, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->listen(io, backlog, out_code);
}

zx_status_t zxio_accept(zxio_t* io, struct sockaddr* addr, socklen_t* addrlen,
                        zxio_storage_t* out_storage, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->accept(io, addr, addrlen, out_storage, out_code);
}

zx_status_t zxio_getsockname(zxio_t* io, struct sockaddr* addr, socklen_t* addrlen,
                             int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->getsockname(io, addr, addrlen, out_code);
}

zx_status_t zxio_getpeername(zxio_t* io, struct sockaddr* addr, socklen_t* addrlen,
                             int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->getpeername(io, addr, addrlen, out_code);
}

zx_status_t zxio_getsockopt(zxio_t* io, int level, int optname, void* optval, socklen_t* optlen,
                            int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->getsockopt(io, level, optname, optval, optlen, out_code);
}

zx_status_t zxio_setsockopt(zxio_t* io, int level, int optname, const void* optval,
                            socklen_t optlen, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->setsockopt(io, level, optname, optval, optlen, out_code);
}

zx_status_t zxio_recvmsg(zxio_t* io, struct msghdr* msg, int flags, size_t* out_actual,
                         int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->recvmsg(io, msg, flags, out_actual, out_code);
}

zx_status_t zxio_sendmsg(zxio_t* io, const struct msghdr* msg, int flags, size_t* out_actual,
                         int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->sendmsg(io, msg, flags, out_actual, out_code);
}

template <typename T>
zx::result<fidl::UnownedClientEnd<T>> connect_socket_provider(
    zxio_service_connector service_connector) {
  zx_handle_t socket_provider_handle;
  zx_status_t status =
      service_connector(fidl::DiscoverableProtocolName<T>, &socket_provider_handle);
  if (status != ZX_OK) {
    return zx::error(status);
  }
  return zx::ok(fidl::UnownedClientEnd<T>(zx::unowned_channel(socket_provider_handle)));
}

zx_status_t zxio_socket(zxio_service_connector service_connector, int domain, int type,
                        int protocol, zxio_storage_alloc allocator, void** out_context,
                        int16_t* out_code) {
  zxio_storage_t* zxio_storage = nullptr;
  fsocket::wire::Domain sock_domain;
  switch (domain) {
    case AF_PACKET: {
      if ((protocol > std::numeric_limits<uint16_t>::max()) ||
          (protocol < std::numeric_limits<uint16_t>::min())) {
        return ZX_ERR_INVALID_ARGS;
      }

      fpacketsocket::wire::Kind kind;
      switch (type) {
        case SOCK_DGRAM:
          kind = fpacketsocket::wire::Kind::kNetwork;
          break;
        case SOCK_RAW:
          kind = fpacketsocket::wire::Kind::kLink;
          break;
        default:
          return ZX_ERR_INVALID_ARGS;
      }

      zx::result<fidl::UnownedClientEnd<fpacketsocket::Provider>> provider =
          connect_socket_provider<fpacketsocket::Provider>(service_connector);
      if (provider.is_error()) {
        return ZX_ERR_IO;
      }
      fidl::WireResult socket_result = fidl::WireCall(provider.value())->Socket(kind);
      if (!socket_result.ok()) {
        return socket_result.status();
      }
      if (socket_result->is_error()) {
        *out_code = static_cast<int16_t>(socket_result->error_value());
        return ZX_OK;
      }
      fidl::ClientEnd<fpacketsocket::Socket>& control = socket_result->value()->socket;
      fidl::WireResult result = fidl::WireCall(control)->Describe();
      if (!result.ok()) {
        return result.status();
      }
      fidl::WireResponse response = result.value();
      if (!response.has_event()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      if (zx_status_t status =
              allocator(ZXIO_OBJECT_TYPE_PACKET_SOCKET, &zxio_storage, out_context);
          status != ZX_OK || zxio_storage == nullptr) {
        return ZX_ERR_NO_MEMORY;
      }
      if (zx_status_t status = zxio_packet_socket_init(zxio_storage, std::move(response.event()),
                                                       std::move(control));
          status != ZX_OK) {
        return status;
      }
      const sockaddr_ll sll = {
          .sll_family = AF_PACKET,
          // NB: protocol is in network byte order.
          .sll_protocol = static_cast<uint16_t>(protocol),
      };

      if (sll.sll_protocol != 0) {
        // We successfully created the packet socket but the caller wants the
        // socket to be associated with some protocol so we do that now.
        if (zx_status_t status = zxio_bind(
                &zxio_storage->io, reinterpret_cast<const sockaddr*>(&sll), sizeof(sll), out_code);
            status != ZX_OK) {
          return status;
        }
      }
      *out_code = 0;
      return ZX_OK;
    }
    case AF_INET:
      sock_domain = fsocket::wire::Domain::kIpv4;
      break;
    case AF_INET6:
      sock_domain = fsocket::wire::Domain::kIpv6;
      break;
    default:
      return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
  }

  switch (type) {
    case SOCK_STREAM:
      switch (protocol) {
        case IPPROTO_IP:
        case IPPROTO_TCP: {
          zx::result<fidl::UnownedClientEnd<fsocket::Provider>> provider =
              connect_socket_provider<fsocket::Provider>(service_connector);
          if (provider.is_error()) {
            return ZX_ERR_IO;
          }
          auto socket_result =
              fidl::WireCall(provider.value())
                  ->StreamSocket(sock_domain, fsocket::wire::StreamSocketProtocol::kTcp);
          if (socket_result.status() != ZX_OK) {
            return socket_result.status();
          }
          if (socket_result->is_error()) {
            *out_code = static_cast<int16_t>(socket_result->error_value());
            return ZX_OK;
          }

          fidl::ClientEnd<fsocket::StreamSocket>& control = socket_result->value()->s;
          fidl::WireResult result = fidl::WireCall(control)->Describe();
          if (!result.ok()) {
            return result.status();
          }
          fidl::WireResponse response = result.value();
          if (!response.has_socket()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          zx_info_socket_t info;
          zx::socket& socket = response.socket();
          if (zx_status_t status =
                  socket.get_info(ZX_INFO_SOCKET, &info, sizeof(info), nullptr, nullptr);
              status != ZX_OK) {
            return status;
          }
          if (zx_status_t status =
                  allocator(ZXIO_OBJECT_TYPE_STREAM_SOCKET, &zxio_storage, out_context);
              status != ZX_OK || zxio_storage == nullptr) {
            return ZX_ERR_NO_MEMORY;
          }
          if (zx_status_t status = zxio_stream_socket_init(
                  zxio_storage, std::move(response.socket()), info, false, std::move(control));
              status != ZX_OK) {
            return status;
          }

        } break;
        default:
          return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
      }
      break;
    case SOCK_DGRAM: {
      fsocket::wire::DatagramSocketProtocol proto;
      switch (protocol) {
        case IPPROTO_IP:
        case IPPROTO_UDP:
          proto = fsocket::wire::DatagramSocketProtocol::kUdp;
          break;
        case IPPROTO_ICMP:
          if (sock_domain != fsocket::wire::Domain::kIpv4) {
            return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
          }
          proto = fsocket::wire::DatagramSocketProtocol::kIcmpEcho;
          break;
        case IPPROTO_ICMPV6:
          if (sock_domain != fsocket::wire::Domain::kIpv6) {
            return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
          }
          proto = fsocket::wire::DatagramSocketProtocol::kIcmpEcho;
          break;
        default:
          return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
      }

      zx::result<fidl::UnownedClientEnd<fsocket::Provider>> provider =
          connect_socket_provider<fsocket::Provider>(service_connector);
      if (provider.is_error()) {
        return ZX_ERR_IO;
      }

      fidl::WireResult socket_result =
          fidl::WireCall(provider.value())->DatagramSocket(sock_domain, proto);
      if (socket_result.status() != ZX_OK) {
        return socket_result.status();
      }
      if (socket_result->is_error()) {
        *out_code = static_cast<int16_t>(socket_result->error_value());
        return ZX_OK;
      }
      fsocket::wire::ProviderDatagramSocketResponse& response = *socket_result->value();
      if (response.has_invalid_tag()) {
        return ZX_ERR_IO;
      }
      switch (response.Which()) {
        case fsocket::wire::ProviderDatagramSocketResponse::Tag::kDatagramSocket: {
          fidl::ClientEnd<fsocket::DatagramSocket>& control = response.datagram_socket();
          fidl::WireResult result = fidl::WireCall(control)->Describe();
          if (!result.ok()) {
            return result.status();
          }
          fidl::WireResponse response = result.value();
          if (!response.has_socket()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (!response.has_tx_meta_buf_size()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (!response.has_rx_meta_buf_size()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (!(response.has_metadata_encoding_protocol_version() &&
                response.metadata_encoding_protocol_version() ==
                    fsocket::UdpMetadataEncodingProtocolVersion::kZero)) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          zx::socket& socket = response.socket();
          zx_info_socket_t info;
          if (zx_status_t status =
                  socket.get_info(ZX_INFO_SOCKET, &info, sizeof(info), nullptr, nullptr);
              status != ZX_OK) {
            return status;
          }
          if (zx_status_t status =
                  allocator(ZXIO_OBJECT_TYPE_DATAGRAM_SOCKET, &zxio_storage, out_context);
              status != ZX_OK || zxio_storage == nullptr) {
            return ZX_ERR_NO_MEMORY;
          }
          if (zx_status_t status = zxio_datagram_socket_init(zxio_storage, std::move(socket), info,
                                                             {
                                                                 response.tx_meta_buf_size(),
                                                                 response.rx_meta_buf_size(),
                                                             },
                                                             std::move(control));
              status != ZX_OK) {
            return status;
          }
        } break;
        case fsocket::wire::ProviderDatagramSocketResponse::Tag::kSynchronousDatagramSocket: {
          fidl::ClientEnd<fsocket::SynchronousDatagramSocket>& control =
              response.synchronous_datagram_socket();
          fidl::WireResult result = fidl::WireCall(control)->Describe();
          if (!result.ok()) {
            return result.status();
          }
          fidl::WireResponse response = result.value();
          if (!response.has_event()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (zx_status_t status = allocator(ZXIO_OBJECT_TYPE_SYNCHRONOUS_DATAGRAM_SOCKET,
                                             &zxio_storage, out_context);
              status != ZX_OK || zxio_storage == nullptr) {
            return ZX_ERR_NO_MEMORY;
          }
          if (zx_status_t status = zxio_synchronous_datagram_socket_init(
                  zxio_storage, std::move(response.event()), std::move(control));
              status != ZX_OK) {
            return status;
          }
        } break;
      }
    } break;
    case SOCK_RAW: {
      if (protocol == 0) {
        return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
      }
      if ((protocol > std::numeric_limits<uint8_t>::max()) ||
          (protocol < std::numeric_limits<uint8_t>::min())) {
        return ZX_ERR_INVALID_ARGS;
      }
      frawsocket::wire::ProtocolAssociation proto_assoc;
      uint8_t sock_protocol = static_cast<uint8_t>(protocol);
      // Sockets created with IPPROTO_RAW are only used to send packets as per
      // https://linux.die.net/man/7/raw,
      //
      //   A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and is able to
      //   send any IP protocol that is specified in the passed header. Receiving
      //   of all IP protocols via IPPROTO_RAW is not possible using raw sockets.
      if (protocol == IPPROTO_RAW) {
        proto_assoc = frawsocket::wire::ProtocolAssociation::WithUnassociated({});
      } else {
        proto_assoc = frawsocket::wire::ProtocolAssociation::WithAssociated(sock_protocol);
      }

      zx::result<fidl::UnownedClientEnd<frawsocket::Provider>> provider =
          connect_socket_provider<frawsocket::Provider>(service_connector);
      if (provider.is_error()) {
        return ZX_ERR_IO;
      }
      fidl::WireResult socket_result =
          fidl::WireCall(provider.value())->Socket(sock_domain, proto_assoc);
      if (!socket_result.ok()) {
        return ZX_ERR_PEER_CLOSED;
      }
      if (socket_result->is_error()) {
        *out_code = static_cast<int16_t>(socket_result->error_value());
        return ZX_OK;
      }
      fidl::ClientEnd<frawsocket::Socket>& control = socket_result->value()->s;
      fidl::WireResult result = fidl::WireCall(control)->Describe();
      if (!result.ok()) {
        return result.status();
      }
      fidl::WireResponse response = result.value();
      if (!response.has_event()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      if (zx_status_t status = allocator(ZXIO_OBJECT_TYPE_RAW_SOCKET, &zxio_storage, out_context);
          status != ZX_OK || zxio_storage == nullptr) {
        return ZX_ERR_NO_MEMORY;
      }
      if (zx_status_t status =
              zxio_raw_socket_init(zxio_storage, std::move(response.event()), std::move(control));
          status != ZX_OK) {
        return status;
      }
    } break;
    default:
      return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
  }

  *out_code = 0;
  return ZX_OK;
}

zx_status_t zxio_read_link(zxio_t* io, const uint8_t** out_target, size_t* out_target_len) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->read_link(io, out_target, out_target_len);
}

zx_status_t zxio_create_symlink(zxio_t* io, const char* name, size_t name_len,
                                const uint8_t* target, size_t target_len, zxio_storage_t* storage) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->create_symlink(io, name, name_len, target, target_len, storage);
}

zx_status_t zxio_xattr_list(zxio_t* io,
                            void (*callback)(void* context, const uint8_t* name, size_t name_len),
                            void* context) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_list(io, callback, context);
}

zx_status_t zxio_xattr_get(zxio_t* io, const uint8_t* name, size_t name_len,
                           zx_status_t (*callback)(void* context, zxio_xattr_data_t data),
                           void* context) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_get(io, name, name_len, callback, context);
}

zx_status_t zxio_xattr_set(zxio_t* io, const uint8_t* name, size_t name_len, const uint8_t* value,
                           size_t value_len, zxio_xattr_set_mode_t mode) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_set(io, name, name_len, value, value_len, mode);
}

zx_status_t zxio_xattr_remove(zxio_t* io, const uint8_t* name, size_t name_len) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_remove(io, name, name_len);
}

zx_status_t zxio_allocate(zxio_t* io, uint64_t offset, uint64_t len, zxio_allocate_mode_t mode) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->allocate(io, offset, len, mode);
}
