// 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 <inttypes.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#include <fbl/ref_ptr.h>
#include <fbl/unique_ptr.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/vfs.h>
#include <fs/vfs.h>
#include <lib/async/dispatcher.h>
#include <lib/memfs/cpp/vnode.h>
#include <lib/memfs/memfs.h>
#include <lib/sync/completion.h>
#include <zircon/device/vfs.h>

#include <utility>

#include "dnode.h"

struct memfs_filesystem {
    memfs::Vfs vfs;

    explicit memfs_filesystem(size_t pages_limit): vfs(pages_limit) { }
};

zx_status_t memfs_create_filesystem(async_dispatcher_t* dispatcher,
                                    memfs_filesystem_t** out_fs,
                                    zx_handle_t* out_root) {
    uint64_t physmem_size = zx_system_get_physmem();
    ZX_DEBUG_ASSERT(physmem_size % PAGE_SIZE == 0);
    size_t page_limit = physmem_size / PAGE_SIZE;

    return memfs_create_filesystem_with_page_limit(dispatcher, page_limit, out_fs, out_root);
}

zx_status_t memfs_create_filesystem_with_page_limit(async_dispatcher_t* dispatcher,
                                                    size_t max_num_pages,
                                                    memfs_filesystem_t** out_fs,
                                                    zx_handle_t* out_root) {
    ZX_DEBUG_ASSERT(dispatcher != nullptr);
    ZX_DEBUG_ASSERT(out_fs != nullptr);
    ZX_DEBUG_ASSERT(out_root != nullptr);

    zx::channel client, server;
    zx_status_t status = zx::channel::create(0, &client, &server);
    if (status != ZX_OK) {
        return status;
    }

    fbl::unique_ptr<memfs_filesystem_t> fs = std::make_unique<memfs_filesystem_t>(max_num_pages);
    fs->vfs.SetDispatcher(dispatcher);

    fbl::RefPtr<memfs::VnodeDir> root;
    if ((status = memfs::CreateFilesystem("<tmp>", &fs->vfs, &root)) != ZX_OK) {
        return status;
    }
    if ((status = fs->vfs.ServeDirectory(std::move(root), std::move(server))) != ZX_OK) {
        return status;
    }

    *out_fs = fs.release();
    *out_root = client.release();
    return ZX_OK;
}

zx_status_t memfs_install_at(async_dispatcher_t* dispatcher, const char* path) {
    uint64_t physmem_size = zx_system_get_physmem();
    ZX_DEBUG_ASSERT(physmem_size % PAGE_SIZE == 0);
    size_t page_limit = physmem_size / PAGE_SIZE;

    return memfs_install_at_with_page_limit(dispatcher, page_limit, path);
}

zx_status_t memfs_install_at_with_page_limit(async_dispatcher_t* dispatcher,
                                             size_t max_num_pages, const char* path) {
    fdio_ns_t* ns;
    zx_status_t status = fdio_ns_get_installed(&ns);
    if (status != ZX_OK) {
        return status;
    }

    memfs_filesystem_t* fs;
    zx_handle_t root;
    status = memfs_create_filesystem_with_page_limit(dispatcher, max_num_pages, &fs, &root);
    if (status != ZX_OK) {
        return status;
    }

    status = fdio_ns_bind(ns, path, root);
    if (status != ZX_OK) {
        memfs_free_filesystem(fs, nullptr);
        return status;
    }

    return ZX_OK;
}

void memfs_free_filesystem(memfs_filesystem_t* fs, sync_completion_t* unmounted) {
    ZX_DEBUG_ASSERT(fs != nullptr);
    fs->vfs.Shutdown([fs, unmounted](zx_status_t status) {
        delete fs;
        if (unmounted) {
            sync_completion_signal(unmounted);
        }
    });
}
