// Copyright 2018 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 <fs/managed-vfs.h>
#include <fs/synchronous-vfs.h>
#include <fs/vfs.h>
#include <fs/vnode.h>
#include <fuchsia/io/c/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/sync/completion.h>
#include <lib/zx/channel.h>
#include <zircon/assert.h>

#include <unittest/unittest.h>

#include <utility>

namespace {

class FdCountVnode : public fs::Vnode {
public:
    FdCountVnode()
        : fd_count_(0) {}
    virtual ~FdCountVnode() {
        ZX_ASSERT(fd_count_ == 0);
    }

    int fds() const {
        return fd_count_;
    }

    zx_status_t Open(uint32_t, fbl::RefPtr<Vnode>* redirect) final {
        fd_count_++;
        return ZX_OK;
    }

    zx_status_t Close() final {
        fd_count_--;
        ZX_ASSERT(fd_count_ >= 0);
        return ZX_OK;
    }

    bool IsDirectory() const final {
        return false;
    }

    zx_status_t GetNodeInfo(uint32_t flags, fuchsia_io_NodeInfo* info) {
        info->tag = fuchsia_io_NodeInfoTag_service;
        return ZX_OK;
    }

private:
    int fd_count_;
};

class AsyncTearDownVnode : public FdCountVnode {
public:
    AsyncTearDownVnode(sync_completion_t* completions)
        : callback_(nullptr), completions_(completions) {}

    ~AsyncTearDownVnode() {
        // C) Tear down the Vnode.
        ZX_ASSERT(fds() == 0);
        sync_completion_signal(&completions_[2]);
    }

private:
    void Sync(fs::Vnode::SyncCallback callback) final {
        callback_ = std::move(callback);
        thrd_t thrd;
        ZX_ASSERT(thrd_create(&thrd, &AsyncTearDownVnode::SyncThread, this) == thrd_success);
        thrd_detach(thrd);
    }

    static int SyncThread(void* arg) {
        fs::Vnode::SyncCallback callback;
        {
            fbl::RefPtr<AsyncTearDownVnode> vn =
                fbl::WrapRefPtr(reinterpret_cast<AsyncTearDownVnode*>(arg));
            // A) Identify when the sync has started being processed.
            sync_completion_signal(&vn->completions_[0]);
            // B) Wait until the connection has been closed.
            sync_completion_wait(&vn->completions_[1], ZX_TIME_INFINITE);
            callback = std::move(vn->callback_);
        }
        callback(ZX_OK);
        return 0;
    }

    fs::Vnode::SyncCallback callback_;
    sync_completion_t* completions_;
};

bool send_sync(const zx::channel& client) {
    BEGIN_HELPER;
    fuchsia_io_NodeSyncRequest request;
    request.hdr.txid = 5;
    request.hdr.ordinal = fuchsia_io_NodeSyncOrdinal;
    ASSERT_EQ(client.write(0, &request, sizeof(request), nullptr, 0), ZX_OK);
    END_HELPER;
}

// Helper function which creates a VFS with a served Vnode,
// starts a sync request, and then closes the connection to the client
// in the middle of the async callback.
//
// This helps tests get ready to try handling a tricky teardown.
bool sync_start(sync_completion_t* completions, async::Loop* loop,
                fbl::unique_ptr<fs::ManagedVfs>* vfs) {
    BEGIN_HELPER;
    *vfs = std::make_unique<fs::ManagedVfs>(loop->dispatcher());
    ASSERT_EQ(loop->StartThread(), ZX_OK);

    auto vn = fbl::AdoptRef(new AsyncTearDownVnode(completions));
    zx::channel client;
    zx::channel server;
    ASSERT_EQ(zx::channel::create(0, &client, &server), ZX_OK);
    ASSERT_EQ(vn->Open(0, nullptr), ZX_OK);
    ASSERT_EQ(vn->Serve(vfs->get(), std::move(server), 0), ZX_OK);
    vn = nullptr;

    ASSERT_TRUE(send_sync(client));

    // A) Wait for sync to begin.
    sync_completion_wait(&completions[0], ZX_TIME_INFINITE);

    client.reset();
    END_HELPER;
}

// Test a case where the VFS object is shut down outside the dispatch loop.
bool TestUnpostedTeardown() {
    BEGIN_TEST;

    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    sync_completion_t completions[3];
    fbl::unique_ptr<fs::ManagedVfs> vfs;

    ASSERT_TRUE(sync_start(completions, &loop, &vfs));

    // B) Let sync complete.
    sync_completion_signal(&completions[1]);

    sync_completion_t* vnode_destroyed = &completions[2];
    sync_completion_t shutdown_done;
    vfs->Shutdown([&vnode_destroyed, &shutdown_done](zx_status_t status) {
        ZX_ASSERT(status == ZX_OK);
        // C) Issue an explicit shutdown, check that the Vnode has
        // already torn down.
        ZX_ASSERT(sync_completion_wait(vnode_destroyed, ZX_SEC(0)) == ZX_OK);
        sync_completion_signal(&shutdown_done);
    });
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_SEC(3)), ZX_OK);
    vfs = nullptr;

    END_TEST;
}

// Test a case where the VFS object is shut down as a posted request to the
// dispatch loop.
bool TestPostedTeardown() {
    BEGIN_TEST;

    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    sync_completion_t completions[3];
    fbl::unique_ptr<fs::ManagedVfs> vfs;

    ASSERT_TRUE(sync_start(completions, &loop, &vfs));

    // B) Let sync complete.
    sync_completion_signal(&completions[1]);

    sync_completion_t* vnode_destroyed = &completions[2];
    sync_completion_t shutdown_done;
    ASSERT_EQ(async::PostTask(loop.dispatcher(), [&]() {
                  vfs->Shutdown([&vnode_destroyed, &shutdown_done](zx_status_t status) {
                      ZX_ASSERT(status == ZX_OK);
                      // C) Issue an explicit shutdown, check that the Vnode has
                      // already torn down.
                      ZX_ASSERT(sync_completion_wait(vnode_destroyed, ZX_SEC(0)) == ZX_OK);
                      sync_completion_signal(&shutdown_done);
                  });
              }),
              ZX_OK);
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_SEC(3)), ZX_OK);
    vfs = nullptr;

    END_TEST;
}

// Test a case where the VFS object destroyed inside the callback to Shutdown.
bool TestTeardownDeleteThis() {
    BEGIN_TEST;

    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    sync_completion_t completions[3];
    fbl::unique_ptr<fs::ManagedVfs> vfs;

    ASSERT_TRUE(sync_start(completions, &loop, &vfs));

    // B) Let sync complete.
    sync_completion_signal(&completions[1]);

    sync_completion_t* vnode_destroyed = &completions[2];
    sync_completion_t shutdown_done;
    fs::ManagedVfs* raw_vfs = vfs.release();
    raw_vfs->Shutdown([&raw_vfs, &vnode_destroyed, &shutdown_done](zx_status_t status) {
        ZX_ASSERT(status == ZX_OK);
        // C) Issue an explicit shutdown, check that the Vnode has
        // already torn down.
        ZX_ASSERT(sync_completion_wait(vnode_destroyed, ZX_SEC(0)) == ZX_OK);
        delete raw_vfs;
        sync_completion_signal(&shutdown_done);
    });
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_SEC(3)), ZX_OK);

    END_TEST;
}

// Test a case where the VFS object is shut down before a background async
// callback gets the chance to complete.
bool TestTeardownSlowAsyncCallback() {
    BEGIN_TEST;

    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    sync_completion_t completions[3];
    fbl::unique_ptr<fs::ManagedVfs> vfs;

    ASSERT_TRUE(sync_start(completions, &loop, &vfs));

    sync_completion_t* vnode_destroyed = &completions[2];
    sync_completion_t shutdown_done;
    vfs->Shutdown([&vnode_destroyed, &shutdown_done](zx_status_t status) {
        ZX_ASSERT(status == ZX_OK);
        // C) Issue an explicit shutdown, check that the Vnode has
        // already torn down.
        //
        // Note: Will not be invoked until (B) completes.
        ZX_ASSERT(sync_completion_wait(vnode_destroyed, ZX_SEC(0)) == ZX_OK);
        sync_completion_signal(&shutdown_done);
    });

    // Shutdown should be waiting for our sync to finish.
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_MSEC(10)), ZX_ERR_TIMED_OUT);

    // B) Let sync complete.
    sync_completion_signal(&completions[1]);
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_SEC(3)), ZX_OK);
    vfs = nullptr;

    END_TEST;
}

// Test a case where the VFS object is shut down while a clone request
// is concurrently trying to open a new connection.
bool TestTeardownSlowClone() {
    BEGIN_TEST;

    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    sync_completion_t completions[3];
    auto vfs = std::make_unique<fs::ManagedVfs>(loop.dispatcher());
    ASSERT_EQ(loop.StartThread(), ZX_OK);

    auto vn = fbl::AdoptRef(new AsyncTearDownVnode(completions));
    zx::channel client, server;
    ASSERT_EQ(zx::channel::create(0, &client, &server), ZX_OK);
    ASSERT_EQ(vn->Open(0, nullptr), ZX_OK);
    ASSERT_EQ(vn->Serve(vfs.get(), std::move(server), 0), ZX_OK);
    vn = nullptr;

    // A) Wait for sync to begin.
    // Block the connection to the server in a sync, while simultanously
    // sending a request to open a new connection.
    send_sync(client);
    sync_completion_wait(&completions[0], ZX_TIME_INFINITE);

    zx::channel client2, server2;
    ASSERT_EQ(zx::channel::create(0, &client2, &server2), ZX_OK);
    ASSERT_EQ(fuchsia_io_NodeClone(client.get(), 0, server2.release()), ZX_OK);

    // The connection is now:
    // - In a sync callback,
    // - Enqueued with a clone request,
    // - Closed.
    client.reset();

    sync_completion_t* vnode_destroyed = &completions[2];
    sync_completion_t shutdown_done;
    vfs->Shutdown([&vnode_destroyed, &shutdown_done](zx_status_t status) {
        ZX_ASSERT(status == ZX_OK);
        // C) Issue an explicit shutdown, check that the Vnode has
        // already torn down.
        //
        // Note: Will not be invoked until (B) completes.
        ZX_ASSERT(sync_completion_wait(vnode_destroyed, ZX_SEC(0)) == ZX_OK);
        sync_completion_signal(&shutdown_done);
    });

    // Shutdown should be waiting for our sync to finish.
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_MSEC(10)), ZX_ERR_TIMED_OUT);

    // B) Let sync complete. This should result in a successful termination
    // of the filesystem, even with the pending clone request.
    sync_completion_signal(&completions[1]);
    ASSERT_EQ(sync_completion_wait(&shutdown_done, ZX_SEC(3)), ZX_OK);
    vfs = nullptr;

    END_TEST;
}

bool TestSynchronousTeardown() {
    BEGIN_TEST;
    async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
    ASSERT_EQ(loop.StartThread(), ZX_OK);
    zx::channel client;

    {
        // Tear down the VFS while the async loop is running.
        auto vfs = std::make_unique<fs::SynchronousVfs>(loop.dispatcher());
        auto vn = fbl::AdoptRef(new FdCountVnode());
        zx::channel server;
        ASSERT_EQ(zx::channel::create(0, &client, &server), ZX_OK);
        ASSERT_EQ(vn->Open(0, nullptr), ZX_OK);
        ASSERT_EQ(vn->Serve(vfs.get(), std::move(server), 0), ZX_OK);
    }

    loop.Quit();

    {
        // Tear down the VFS while the async loop is not running.
        auto vfs = std::make_unique<fs::SynchronousVfs>(loop.dispatcher());
        auto vn = fbl::AdoptRef(new FdCountVnode());
        zx::channel server;
        ASSERT_EQ(zx::channel::create(0, &client, &server), ZX_OK);
        ASSERT_EQ(vn->Open(0, nullptr), ZX_OK);
        ASSERT_EQ(vn->Serve(vfs.get(), std::move(server), 0), ZX_OK);
    }

    {
        // Tear down the VFS with no active connections.
        auto vfs = std::make_unique<fs::SynchronousVfs>(loop.dispatcher());
    }

    END_TEST;
}

} // namespace

BEGIN_TEST_CASE(teardown_tests)
RUN_TEST(TestUnpostedTeardown)
RUN_TEST(TestPostedTeardown)
RUN_TEST(TestTeardownDeleteThis)
RUN_TEST(TestTeardownSlowAsyncCallback)
RUN_TEST(TestTeardownSlowClone)
RUN_TEST(TestSynchronousTeardown)
END_TEST_CASE(teardown_tests)
