// Copyright 2019 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/fdio/fdio.h>
#include <lib/zxio/ops.h>
#include <zircon/errors.h>

#include <variant>

#include <fbl/auto_lock.h>

#include "fdio_unistd.h"
#include "internal.h"
#include "zxio.h"

__EXPORT
fdio_t* fdio_default_create(void) {
  zx::status io = fdio_internal::zxio::create();
  if (io.is_error()) {
    return nullptr;
  }
  std::variant reference = GetLastReference(std::move(io.value()));
  return std::get<fdio::last_reference>(reference).ExportToRawPtr();
}

__EXPORT
fdio_t* fdio_null_create(void) {
  zx::status io = fdio_internal::zxio::create_null();
  if (io.is_error()) {
    return nullptr;
  }
  std::variant reference = GetLastReference(std::move(io.value()));
  return std::get<fdio::last_reference>(reference).ExportToRawPtr();
}

__EXPORT
zx_status_t fdio_create(zx_handle_t h, fdio_t** out_io) {
  zx::status io = fdio::create(zx::handle(h));
  if (io.is_ok()) {
    std::variant reference = GetLastReference(std::move(io.value()));
    *out_io = std::get<fdio::last_reference>(reference).ExportToRawPtr();
  }
  return io.status_value();
}

__EXPORT
int fdio_fd_create_null(void) {
  zx::status io = fdio_internal::zxio::create_null();
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  std::optional fd = bind_to_fd(io.value());
  if (fd.has_value()) {
    return fd.value();
  }
  return ERRNO(EMFILE);
}

__EXPORT
extern "C" zxio_t* fdio_get_zxio(fdio_t* io) { return &io->zxio_storage().io; }

__EXPORT
int fdio_bind_to_fd(fdio_t* io, int fd, int starting_fd) {
  fdio_ptr owned = fbl::ImportFromRawPtr(io);
  // If we are not given an |fd|, the |starting_fd| must be non-negative.
  if ((fd < 0 && starting_fd < 0) || fd >= FDIO_MAX_FD) {
    return ERRNO(EINVAL);
  }

  // Don't release under lock.
  fdio_ptr io_to_close = nullptr;
  {
    fbl::AutoLock lock(&fdio_lock);
    if (fd < 0) {
      // A negative fd implies that any free fd value can be used
      // TODO: bitmap, ffs, etc
      for (fd = starting_fd; fd < FDIO_MAX_FD; fd++) {
        if (fdio_fdtab[fd].try_set(owned)) {
          return fd;
        }
      }
      return ERRNO(EMFILE);
    }
    io_to_close = fdio_fdtab[fd].replace(owned);
  }
  return fd;
}

__EXPORT
zx_status_t fdio_unbind_from_fd(int fd, fdio_t** out) {
  fdio_ptr io = unbind_from_fd(fd);
  if (io == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  std::variant reference = GetLastReference(std::move(io));
  auto* ptr = std::get_if<fdio::last_reference>(&reference);
  if (ptr) {
    *out = ptr->ExportToRawPtr();
    return ZX_OK;
  }
  return ZX_ERR_UNAVAILABLE;
}

__EXPORT
zx_status_t fdio_get_service_handle(int fd, zx_handle_t* out) {
  fdio_ptr io = unbind_from_fd(fd);
  if (io == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  std::variant reference = GetLastReference(std::move(io));
  auto* ptr = std::get_if<fdio::last_reference>(&reference);
  if (ptr) {
    return ptr->unwrap(out);
  }
  return ZX_ERR_UNAVAILABLE;
}

__EXPORT
fdio_t* fdio_zxio_create(zxio_storage_t** out_storage) {
  zx::status io = fdio_internal::zxio::create();
  if (io.is_error()) {
    return nullptr;
  }
  *out_storage = &io->zxio_storage();
  std::variant reference = GetLastReference(std::move(io.value()));
  return std::get<fdio::last_reference>(reference).ExportToRawPtr();
}
