// Copyright 2017 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/namespace/namespace.h"

#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/namespace.h>
#include <lib/zx/channel.h>
#include <zircon/types.h>

#include <cerrno>

#include <fbl/auto_lock.h>
#include <fbl/ref_ptr.h>

#include "fidl/fuchsia.io/cpp/wire_types.h"
#include "sdk/lib/fdio/cleanpath.h"
#include "sdk/lib/fdio/fdio_state.h"
#include "sdk/lib/fdio/fdio_unistd.h"
#include "sdk/lib/fdio/internal.h"
#include "sdk/lib/fdio/namespace/local-connection.h"
#include "sdk/lib/fdio/namespace/local-filesystem.h"
#include "sdk/lib/fdio/unistd.h"

namespace fio = fuchsia_io;

zx::result<fbl::RefPtr<fdio>> fdio_ns_open_root(fdio_ns_t* ns) { return ns->OpenRoot(); }

zx_status_t fdio_ns_set_root(fdio_ns_t* ns, fdio_t* io) { return ns->SetRoot(io); }

__BEGIN_CDECLS

__EXPORT
zx_status_t fdio_ns_connect(fdio_ns_t* ns, const char* path, uint32_t flags, zx_handle_t request) {
  if (static_cast<fio::wire::OpenFlags>(flags) & fio::wire::OpenFlags::kDescribe) {
    return ZX_ERR_INVALID_ARGS;
  }
  return fdio_ns_open(ns, path, flags, request);
}

__EXPORT
zx_status_t fdio_ns_open(fdio_ns_t* ns, const char* path, uint32_t flags, zx_handle_t request) {
  if (path == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  fdio_internal::PathBuffer clean;
  bool is_dir;
  if (!fdio_internal::CleanPath(path, &clean, &is_dir)) {
    return ZX_ERR_BAD_PATH;
  }
  auto remote = fidl::ServerEnd<fio::Node>(zx::channel(request));
  return ns->Connect(clean, static_cast<fio::wire::OpenFlags>(flags), std::move(remote));
}

__EXPORT
zx_status_t fdio_ns_service_connect(fdio_ns_t* ns, const char* path, zx_handle_t request) {
  return fdio_ns_open(ns, path, 0, request);
}

__EXPORT
zx_status_t fdio_ns_create(fdio_ns_t** out) {
  // Create a ref-counted object, and leak the reference that is returned
  // via the C API.
  //
  // This reference is reclaimed in fdio_ns_destroy.
  fbl::RefPtr<fdio_namespace> ns = fdio_namespace::Create();
  *out = fbl::ExportToRawPtr(&ns);
  return ZX_OK;
}

__EXPORT
zx_status_t fdio_ns_destroy(fdio_ns_t* raw_ns) {
  // This function reclaims a reference which was leaked in fdio_ns_create.
  [[maybe_unused]] auto ns = fbl::ImportFromRawPtr<fdio_namespace>(raw_ns);
  return ZX_OK;
}

__EXPORT
zx_status_t fdio_ns_bind_local(fdio_ns_t* ns, const char* path, fdio_open_local_func_t on_open,
                               void* context) {
  if (path == nullptr || on_open == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  fdio_internal::PathBuffer clean;
  bool is_dir;
  if (!fdio_internal::CleanPath(path, &clean, &is_dir)) {
    return ZX_ERR_BAD_PATH;
  }
  if (is_dir) {
    // Local binding are always files.
    return ZX_ERR_INVALID_ARGS;
  }
  return ns->Bind(clean, on_open, context);
}

__EXPORT
zx_status_t fdio_ns_bind(fdio_ns_t* ns, const char* path, zx_handle_t remote_raw) {
  if (path == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  fdio_internal::PathBuffer clean;
  bool is_dir;
  if (!fdio_internal::CleanPath(path, &clean, &is_dir)) {
    return ZX_ERR_BAD_PATH;
  }
  auto remote = fidl::ClientEnd<fio::Directory>(zx::channel(remote_raw));
  return ns->Bind(clean, std::move(remote));
}

__EXPORT
zx_status_t fdio_ns_unbind(fdio_ns_t* ns, const char* path) {
  if (path == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  fdio_internal::PathBuffer clean;
  bool is_dir;
  if (!fdio_internal::CleanPath(path, &clean, &is_dir)) {
    return ZX_ERR_BAD_PATH;
  }
  return ns->Unbind(clean);
}

__EXPORT
bool fdio_ns_is_bound(fdio_ns_t* ns, const char* path) {
  if (path == nullptr) {
    return false;
  }
  fdio_internal::PathBuffer clean;
  bool is_dir;
  if (!fdio_internal::CleanPath(path, &clean, &is_dir)) {
    return false;
  }
  return ns->IsBound(clean);
}

__EXPORT
zx_status_t fdio_ns_bind_fd(fdio_ns_t* ns, const char* path, int fd) {
  zx_handle_t handle = ZX_HANDLE_INVALID;
  zx_status_t status = fdio_fd_clone(fd, &handle);
  if (status != ZX_OK) {
    return status;
  }

  return fdio_ns_bind(ns, path, handle);
}

__EXPORT
int fdio_ns_opendir(fdio_ns_t* ns) {
  zx::result io = ns->OpenRoot();
  if (io.is_error()) {
    errno = ENOMEM;
    return -1;
  }
  std::optional fd = bind_to_fd(io.value());
  if (fd.has_value()) {
    return fd.value();
  }
  return ERRNO(EMFILE);
}

__EXPORT
zx_status_t fdio_ns_chdir(fdio_ns_t* ns) {
  zx::result io = ns->OpenRoot();
  if (io.is_error()) {
    return ZX_ERR_NO_MEMORY;
  }
  fdio_chdir(io.value(), "/");
  return ZX_OK;
}

__EXPORT
zx_status_t fdio_ns_export(fdio_ns_t* ns, fdio_flat_namespace_t** out) { return ns->Export(out); }

__EXPORT
zx_status_t fdio_ns_export_root(fdio_flat_namespace_t** out) {
  fbl::AutoLock lock(&fdio_lock);
  return fdio_ns_export(fdio_root_ns, out);
}

__EXPORT
void fdio_ns_free_flat_ns(fdio_flat_namespace_t* ns) {
  zx_handle_close_many(ns->handle, ns->count);
  free(ns);
}

__END_CDECLS
