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

#include <lib/zxio/types.h>

#include "internal.h"

fdio::~fdio() = default;

zx::status<fdio_ptr> fdio::open(std::string_view path, fuchsia_io::wire::OpenFlags flags,
                                uint32_t mode) {
  return zx::error(ZX_ERR_NOT_SUPPORTED);
}

zx_status_t fdio::add_inotify_filter(std::string_view path, uint32_t mask,
                                     uint32_t watch_descriptor, zx::socket socket) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::clone(zx_handle_t* out_handle) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::unwrap(zx_handle_t* out_handle) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::borrow_channel(zx_handle_t* out_handle) { return ZX_ERR_NOT_SUPPORTED; }

void fdio::wait_begin(uint32_t events, zx_handle_t* out_handle, zx_signals_t* out_signals) {
  *out_handle = ZX_HANDLE_INVALID;
}

void fdio::wait_end(zx_signals_t signals, uint32_t* out_events) {}

Errno fdio::posix_ioctl(int req, va_list va) { return Errno(ENOTTY); }

zx_status_t fdio::get_token(zx_handle_t* out) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::get_attr(zxio_node_attributes_t* out) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::set_attr(const zxio_node_attributes_t* attr) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::dirent_iterator_init(zxio_dirent_iterator_t* iterator, zxio_t* directory) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::dirent_iterator_next(zxio_dirent_iterator_t* iterator,
                                       zxio_dirent_t* inout_entry) {
  return ZX_ERR_NOT_SUPPORTED;
}

void fdio::dirent_iterator_destroy(zxio_dirent_iterator_t* iterator) {}

zx_status_t fdio::watch_directory(zxio_watch_directory_cb cb, zx_time_t deadline, void* context) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::unlink(std::string_view name, int flags) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::truncate(uint64_t off) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::rename(std::string_view src, zx_handle_t dst_token, std::string_view dst) {
  zx_handle_close(dst_token);
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::link(std::string_view src, zx_handle_t dst_token, std::string_view dst) {
  zx_handle_close(dst_token);
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::get_flags(fuchsia_io::wire::OpenFlags* out_flags) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::set_flags(fuchsia_io::wire::OpenFlags flags) { return ZX_ERR_NOT_SUPPORTED; }

zx_status_t fdio::bind(const struct sockaddr* addr, socklen_t addrlen, int16_t* out_code) {
  *out_code = EBADF;
  return ZX_OK;
}

zx_status_t fdio::connect(const struct sockaddr* addr, socklen_t addrlen, int16_t* out_code) {
  *out_code = EBADF;
  return ZX_OK;
}

zx_status_t fdio::listen(int backlog, int16_t* out_code) { return ZX_ERR_WRONG_TYPE; }

zx_status_t fdio::accept(int flags, struct sockaddr* addr, socklen_t* addrlen,
                         zx_handle_t* out_handle, int16_t* out_code) {
  return ZX_ERR_WRONG_TYPE;
}

zx_status_t fdio::getsockname(struct sockaddr* addr, socklen_t* addrlen, int16_t* out_code) {
  *out_code = EBADF;
  return ZX_OK;
}

zx_status_t fdio::getpeername(struct sockaddr* addr, socklen_t* addrlen, int16_t* out_code) {
  *out_code = EBADF;
  return ZX_OK;
}

zx_status_t fdio::getsockopt(int level, int optname, void* optval, socklen_t* optlen,
                             int16_t* out_code) {
  *out_code = EBADF;
  return ZX_OK;
}

zx_status_t fdio::setsockopt(int level, int optname, const void* optval, socklen_t optlen,
                             int16_t* out_code) {
  *out_code = EBADF;
  return ZX_OK;
}

zx_status_t fdio::recvmsg(struct msghdr* msg, int flags, size_t* out_actual, int16_t* out_code) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::sendmsg(const struct msghdr* msg, int flags, size_t* out_actual,
                          int16_t* out_code) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t fdio::shutdown(int how, int16_t* out_code) { return ZX_ERR_WRONG_TYPE; }

std::variant<fdio::last_reference, fdio_ptr> GetLastReference(fdio_ptr io) {
  if (io->IsLastReference()) {
    return fdio::last_reference(fbl::ExportToRawPtr(&io));
  }
  return std::move(io);
}
