// Copyright 2020 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 "sdk/lib/fdio/fdio_unistd.h"

#include <fbl/auto_lock.h>

#include "sdk/lib/fdio/internal.h"

std::optional<int> bind_to_fd(const fbl::RefPtr<fdio>& io) {
  fbl::AutoLock lock(&fdio_lock);
  return bind_to_fd_locked(io);
}

std::optional<int> bind_to_fd_locked(const fbl::RefPtr<fdio>& io) {
  for (size_t fd = 0; fd < fdio_fdtab.size(); ++fd) {
    if (fdio_fdtab[fd].try_set(io)) {
      return fd;
    }
  }
  return std::nullopt;
}

namespace {

fdio_slot* slot_locked(int fd) __TA_REQUIRES(fdio_lock) {
  if ((fd < 0) || (fd >= FDIO_MAX_FD)) {
    return nullptr;
  }
  return &fdio_fdtab[fd];
}

}  // namespace

fbl::RefPtr<fdio> fd_to_io(int fd) {
  fbl::AutoLock lock(&fdio_lock);
  return fd_to_io_locked(fd);
}

fbl::RefPtr<fdio> fd_to_io_locked(int fd) {
  fdio_slot* slot = slot_locked(fd);
  if (slot == nullptr) {
    return nullptr;
  }
  return slot->get();
}

fbl::RefPtr<fdio> unbind_from_fd(int fd) {
  fbl::AutoLock lock(&fdio_lock);
  return unbind_from_fd_locked(fd);
}

fbl::RefPtr<fdio> unbind_from_fd_locked(int fd) __TA_REQUIRES(fdio_lock) {
  fdio_slot* slot = slot_locked(fd);
  if (slot == nullptr) {
    return nullptr;
  }
  return slot->release();
}

// TODO(https://fxbug.dev/42105838): determine complete correct mapping
int fdio_status_to_errno(zx_status_t status) {
  switch (status) {
    case ZX_ERR_NOT_FOUND:
      return ENOENT;
    case ZX_ERR_NO_MEMORY:
      return ENOMEM;
    case ZX_ERR_INVALID_ARGS:
      return EINVAL;
    case ZX_ERR_BUFFER_TOO_SMALL:
      return EINVAL;
    case ZX_ERR_TIMED_OUT:
      return ETIMEDOUT;
    case ZX_ERR_UNAVAILABLE:
      return EBUSY;
    case ZX_ERR_ALREADY_EXISTS:
      return EEXIST;
    case ZX_ERR_PEER_CLOSED:
      return EPIPE;
    case ZX_ERR_BAD_STATE:
      return EPIPE;
    case ZX_ERR_BAD_PATH:
      return ENAMETOOLONG;
    case ZX_ERR_IO:
      return EIO;
    case ZX_ERR_NOT_FILE:
      return EISDIR;
    case ZX_ERR_NOT_DIR:
      return ENOTDIR;
    case ZX_ERR_NOT_SUPPORTED:
      return ENOTSUP;
    case ZX_ERR_WRONG_TYPE:
      return ENOTSUP;
    case ZX_ERR_OUT_OF_RANGE:
      return EINVAL;
    case ZX_ERR_NO_RESOURCES:
      return ENOMEM;
    case ZX_ERR_BAD_HANDLE:
      return EBADF;
    case ZX_ERR_ACCESS_DENIED:
      return EACCES;
    case ZX_ERR_SHOULD_WAIT:
      return EAGAIN;
    case ZX_ERR_FILE_BIG:
      return EFBIG;
    case ZX_ERR_NO_SPACE:
      return ENOSPC;
    case ZX_ERR_NOT_EMPTY:
      return ENOTEMPTY;
    case ZX_ERR_IO_REFUSED:
      return ECONNREFUSED;
    case ZX_ERR_IO_INVALID:
      return EIO;
    case ZX_ERR_CANCELED:
      return EBADF;
    case ZX_ERR_PROTOCOL_NOT_SUPPORTED:
      return EPROTONOSUPPORT;
    case ZX_ERR_ADDRESS_UNREACHABLE:
      return ENETUNREACH;
    case ZX_ERR_ADDRESS_IN_USE:
      return EADDRINUSE;
    case ZX_ERR_NOT_CONNECTED:
      return ENOTCONN;
    case ZX_ERR_CONNECTION_REFUSED:
      return ECONNREFUSED;
    case ZX_ERR_CONNECTION_RESET:
      return ECONNRESET;
    case ZX_ERR_CONNECTION_ABORTED:
      return ECONNABORTED;

    // No specific translation, so return a generic value.
    default:
      return EIO;
  }
}
