// Copyright 2020 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 "src/ui/scenic/lib/flatland/flatland_manager.h"

#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/fit/function.h>

namespace flatland {

FlatlandManager::FlatlandManager(
    const std::shared_ptr<FlatlandPresenter>& flatland_presenter,
    const std::shared_ptr<UberStructSystem>& uber_struct_system,
    const std::shared_ptr<LinkSystem>& link_system,
    const std::vector<std::shared_ptr<BufferCollectionImporter>>& buffer_collection_importers)
    : flatland_presenter_(flatland_presenter),
      uber_struct_system_(uber_struct_system),
      link_system_(link_system),
      buffer_collection_importers_(buffer_collection_importers) {}

void FlatlandManager::CreateFlatland(
    fidl::InterfaceRequest<fuchsia::ui::scenic::internal::Flatland> request) {
  const scheduling::SessionId id = uber_struct_system_->GetNextInstanceId();
  FX_DCHECK(flatland_instances_.find(id) == flatland_instances_.end());

  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator;
  zx_status_t status = fdio_service_connect("/svc/fuchsia.sysmem.Allocator",
                                            sysmem_allocator.NewRequest().TakeChannel().release());
  FX_DCHECK(status == ZX_OK);

  auto flatland = std::make_unique<Flatland>(
      id, flatland_presenter_, link_system_, uber_struct_system_->AllocateQueueForSession(id),
      buffer_collection_importers_, std::move(sysmem_allocator));

  auto result = flatland_instances_.emplace(
      id, std::make_unique<FlatlandInstance>(request.channel(), std::move(flatland)));
  FX_DCHECK(result.second);

  auto& instance = result.first->second;
  instance->binding.Bind(std::move(request), instance->loop.dispatcher());

  // Run the waiter on the main thread, not the instance thread, so that it can clean up and join
  // the instance thread.
  status = instance->peer_closed_waiter.Begin(
      async_get_default_dispatcher(),
      [this, id](async_dispatcher_t* dispatcher, async::WaitOnce* wait, zx_status_t status,
                 const zx_packet_signal_t* signal) { this->RemoveFlatlandInstance(id); });
  FX_DCHECK(status == ZX_OK);

  const std::string name = "Flatland ID=" + std::to_string(id);
  status = instance->loop.StartThread(name.c_str());
  FX_DCHECK(status == ZX_OK);
}

size_t FlatlandManager::GetSessionCount() const { return flatland_instances_.size(); }

void FlatlandManager::RemoveFlatlandInstance(scheduling::SessionId session_id) {
  auto instance_kv = flatland_instances_.find(session_id);
  FX_DCHECK(instance_kv != flatland_instances_.end());

  // The fidl::Binding must be destroyed on the thread that owns the looper it is bound to. Remove
  // the instance from the map, then push cleanup onto the worker thread. Note that the closure
  // exists only to transfer the cleanup responsibilities to the worker thread.
  async::PostTask(instance_kv->second->loop.dispatcher(),
                  [instance = std::move(instance_kv->second)]() {});

  // Other resource cleanup can safely occur on the main thread.
  flatland_instances_.erase(session_id);
  uber_struct_system_->RemoveSession(session_id);
}

}  // namespace flatland
