// Copyright 2018 The Chromium 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 "base/fuchsia/service_directory.h"

#include <lib/async/default.h>
#include <lib/svc/dir.h>
#include <lib/zx/channel.h>
#include <zircon/process.h>
#include <zircon/processargs.h>

#include "base/fuchsia/fuchsia_logging.h"
#include "base/message_loop/message_loop_current.h"
#include "base/no_destructor.h"
#include "starboard/types.h"

namespace base {
namespace fuchsia {

ServiceDirectory::ServiceDirectory(zx::channel directory_request) {
  zx_status_t status = svc_dir_create(async_get_default_dispatcher(),
                                      directory_request.release(), &svc_dir_);
  ZX_CHECK(status == ZX_OK, status);
}

ServiceDirectory::~ServiceDirectory() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(services_.empty());

  zx_status_t status = svc_dir_destroy(svc_dir_);
  ZX_DCHECK(status == ZX_OK, status);
}

// static
ServiceDirectory* ServiceDirectory::GetDefault() {
  static base::NoDestructor<ServiceDirectory> directory(
      zx::channel(zx_take_startup_handle(PA_DIRECTORY_REQUEST)));
  return directory.get();
}

void ServiceDirectory::AddService(StringPiece name,
                                  ConnectServiceCallback connect_callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(services_.find(name) == services_.end());

  std::string name_str = name.as_string();
  services_[name_str] = connect_callback;

  zx_status_t status =
      svc_dir_add_service(svc_dir_, "public", name_str.c_str(), this,
                          &ServiceDirectory::HandleConnectRequest);
  ZX_DCHECK(status == ZX_OK, status);

  // Publish to the legacy "flat" namespace, which is required by some clients.
  status = svc_dir_add_service(svc_dir_, nullptr, name_str.c_str(), this,
                               &ServiceDirectory::HandleConnectRequest);
  ZX_DCHECK(status == ZX_OK, status);
}

void ServiceDirectory::RemoveService(StringPiece name) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  std::string name_str = name.as_string();

  auto it = services_.find(name_str);
  DCHECK(it != services_.end());
  services_.erase(it);

  zx_status_t status =
      svc_dir_remove_service(svc_dir_, "public", name_str.c_str());
  ZX_DCHECK(status == ZX_OK, status);

  // Unregister from the legacy "flat" namespace.
  status = svc_dir_remove_service(svc_dir_, nullptr, name_str.c_str());
  ZX_DCHECK(status == ZX_OK, status);
}

void ServiceDirectory::RemoveAllServices() {
  while (!services_.empty()) {
    RemoveService(services_.begin()->first);
  }
}

// static
void ServiceDirectory::HandleConnectRequest(void* context,
                                            const char* service_name,
                                            zx_handle_t service_request) {
  auto* directory = reinterpret_cast<ServiceDirectory*>(context);
  DCHECK_CALLED_ON_VALID_THREAD(directory->thread_checker_);

  auto it = directory->services_.find(service_name);

  // HandleConnectRequest() is expected to be called only for registered
  // services.
  DCHECK(it != directory->services_.end());

  it->second.Run(zx::channel(service_request));
}

}  // namespace fuchsia
}  // namespace base
