// 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 <errno.h>
#include <fcntl.h>

#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/directory.h>
#include <lib/zx/channel.h>
#include <zircon/types.h>
#include <zircon/processargs.h>
#include <zircon/device/vfs.h>

#include "local-connection.h"
#include "local-filesystem.h"
#include "local-vnode.h"

__BEGIN_CDECLS

__EXPORT
zx_status_t fdio_ns_connect(fdio_ns_t* ns, const char* path, uint32_t flags,
                            zx_handle_t raw_handle) {
    zx::channel channel(raw_handle);
    return ns->Connect(path, flags, std::move(channel));
}

__EXPORT
zx_status_t fdio_ns_open(fdio_ns_t* ns, const char* path, uint32_t flags, zx_handle_t* out) {
    zx::channel client, server;
    if (zx::channel::create(0, &client, &server) != ZX_OK) {
        return ZX_ERR_INTERNAL;
    }
    zx_status_t status = fdio_ns_connect(ns, path, flags, server.release());
    if (status != ZX_OK) {
        return status;
    }
    *out = client.release();
    return ZX_OK;
}

__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 = ns.leak_ref();
    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.
    __UNUSED auto ns = fbl::internal::MakeRefPtrNoAdopt<fdio_namespace>(raw_ns);
    return ZX_OK;
}

__EXPORT
zx_status_t fdio_ns_bind(fdio_ns_t* ns, const char* path, zx_handle_t remote_raw) {
    zx::channel remote(remote_raw);
    return ns->Bind(path, std::move(remote));
}

__EXPORT
zx_status_t fdio_ns_unbind(fdio_ns_t* ns, const char* path) {
    return ns->Unbind(path);
}

__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);
}

fdio_t* fdio_ns_open_root(fdio_ns_t* ns) {
    return ns->OpenRoot();
}

__EXPORT
int fdio_ns_opendir(fdio_ns_t* ns) {
    fdio_t* io = ns->OpenRoot();
    if (io == nullptr) {
        errno = ENOMEM;
        return -1;
    }
    int fd = fdio_bind_to_fd(io, -1, 0);
    if (fd < 0) {
        fdio_release(io);
        errno = ENOMEM;
    }
    return fd;
}

__EXPORT
zx_status_t fdio_ns_chdir(fdio_ns_t* ns) {
    fdio_t* io = ns->OpenRoot();
    if (io == nullptr) {
        return ZX_ERR_NO_MEMORY;
    }
    fdio_chdir(io, "/");
    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) {
    zx_status_t status;
    mtx_lock(&fdio_lock);
    if (fdio_root_ns == nullptr) {
        status = ZX_ERR_NOT_FOUND;
    } else {
        status = fdio_ns_export(fdio_root_ns, out);
    }
    mtx_unlock(&fdio_lock);
    return status;
}

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

__END_CDECLS
