// Copyright 2016 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 <fbl/unique_ptr.h>
#include <lib/async/cpp/task.h>
#include <lib/sync/completion.h>

#include <utility>

namespace fs {

ManagedVfs::ManagedVfs() : is_shutting_down_(false) {}

ManagedVfs::ManagedVfs(async_dispatcher_t* dispatcher) : Vfs(dispatcher), is_shutting_down_(false) {}

ManagedVfs::~ManagedVfs() {
    ZX_DEBUG_ASSERT(connections_.is_empty());
}

bool ManagedVfs::IsTerminated() const {
    return is_shutting_down_ && connections_.is_empty();
}

// Asynchronously drop all connections.
void ManagedVfs::Shutdown(ShutdownCallback handler) {
    ZX_DEBUG_ASSERT(handler);
    zx_status_t status = async::PostTask(dispatcher(), [this, closure = std::move(handler)]() mutable {
        ZX_DEBUG_ASSERT(!shutdown_handler_);
        shutdown_handler_ = std::move(closure);
        is_shutting_down_ = true;

        UninstallAll(ZX_TIME_INFINITE);

        // Signal the teardown on channels in a way that doesn't potentially
        // pull them out from underneath async callbacks.
        for (auto& c : connections_) {
            c.AsyncTeardown();
        }

        CheckForShutdownComplete();
    });
    ZX_DEBUG_ASSERT(status == ZX_OK);
}

// Trigger "OnShutdownComplete" if all preconditions have been met.
void ManagedVfs::CheckForShutdownComplete() {
    if (IsTerminated()) {
        shutdown_task_.Post(dispatcher());
    }
}

void ManagedVfs::OnShutdownComplete(async_dispatcher_t*, async::TaskBase*, zx_status_t status) {
    ZX_ASSERT_MSG(IsTerminated(),
                  "Failed to complete VFS shutdown: dispatcher status = %d\n", status);
    ZX_DEBUG_ASSERT(shutdown_handler_);

    auto handler = std::move(shutdown_handler_);
    handler(status);
}

void ManagedVfs::RegisterConnection(fbl::unique_ptr<Connection> connection) {
    ZX_DEBUG_ASSERT(!is_shutting_down_);
    connections_.push_back(std::move(connection));
}

void ManagedVfs::UnregisterConnection(Connection* connection) {
    // We drop the result of |erase| on the floor, effectively destroying the
    // connection when all other references (like async callbacks) have
    // completed.
    connections_.erase(*connection);
    CheckForShutdownComplete();
}

bool ManagedVfs::IsTerminating() const {
    return is_shutting_down_;
}

} // namespace fs
