// 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 "lib/svc/cpp/service_provider_bridge.h"

#include <fcntl.h>
#include <fdio/util.h>
#include <zircon/device/vfs.h>

#include <utility>

#include "lib/fsl/tasks/message_loop.h"

namespace app {

ServiceProviderBridge::ServiceProviderBridge()
    : vfs_(fsl::MessageLoop::GetCurrent()->async()),
      directory_(fbl::AdoptRef(new svcfs::VnodeProviderDir())) {
  directory_->SetServiceProvider(this);
}

ServiceProviderBridge::~ServiceProviderBridge() {
  directory_->SetServiceProvider(nullptr);
}

void ServiceProviderBridge::AddBinding(
    fidl::InterfaceRequest<app::ServiceProvider> request) {
  bindings_.AddBinding(this, std::move(request));
}

void ServiceProviderBridge::AddServiceForName(ServiceConnector connector,
                                              const std::string& service_name) {
  name_to_service_connector_[service_name] = std::move(connector);
}

bool ServiceProviderBridge::ServeDirectory(zx::channel channel) {
  return vfs_.ServeDirectory(directory_, std::move(channel)) == ZX_OK;
}

zx::channel ServiceProviderBridge::OpenAsDirectory() {
  zx::channel h1, h2;
  if (zx::channel::create(0, &h1, &h2) < 0)
    return zx::channel();
  if (!ServeDirectory(std::move(h1)))
    return zx::channel();
  return h2;
}

int ServiceProviderBridge::OpenAsFileDescriptor() {
  zx::channel h1, h2;
  if (zx::channel::create(0, &h1, &h2) < 0)
    return -1;
  if (!ServeDirectory(std::move(h1)))
    return -1;
  fdio_t* io = fdio_remote_create(h2.release(), ZX_HANDLE_INVALID);
  if (!io)
    return -1;
  return fdio_bind_to_fd(io, -1, 0);
}

void ServiceProviderBridge::Connect(const char* name,
                                    size_t len,
                                    zx::channel channel) {
  ConnectToService(fidl::String(name, len), std::move(channel));
}

void ServiceProviderBridge::ConnectToService(const fidl::String& service_name,
                                             zx::channel channel) {
  auto it = name_to_service_connector_.find(service_name.get());
  if (it != name_to_service_connector_.end())
    it->second(std::move(channel));
  else
    backend_->ConnectToService(std::move(service_name), std::move(channel));
}

}  // namespace app
