// Copyright 2019 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/fdio/vfs.h>
#include <lib/fidl/cpp/event_sender.h>
#include <lib/vfs/cpp/flags.h>
#include <lib/vfs/cpp/service.h>

namespace vfs {

Service::Service(Connector connector) : connector_(std::move(connector)) {}

Service::~Service() = default;

void Service::Describe(fuchsia::io::NodeInfo* out_info) {
  out_info->set_service(fuchsia::io::Service());
}

void Service::Describe2(fuchsia::io::ConnectionInfo* out_info) {
  out_info->set_representation(
      fuchsia::io::Representation::WithConnector(fuchsia::io::ConnectorInfo()));
}

zx_status_t Service::CreateConnection(fuchsia::io::OpenFlags flags,
                                      std::unique_ptr<vfs::internal::Connection>* connection) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Service::Connect(fuchsia::io::OpenFlags flags, zx::channel request,
                             async_dispatcher_t* dispatcher) {
  if (Flags::IsNodeReference(flags)) {
    // Node::Connect will send an OnOpen event if OPEN_FLAG_DESCRIBE is set.
    return Node::Connect(flags, std::move(request), dispatcher);
  }
  // Send OnOpen event if required before switching from the |Node| protocol back to the service.
  if (Flags::ShouldDescribe(flags)) {
    fidl::EventSender<fuchsia::io::Node> sender(std::move(request));
    std::unique_ptr<fuchsia::io::NodeInfo> node_info = std::make_unique<fuchsia::io::NodeInfo>();
    Describe(node_info.get());
    sender.events().OnOpen(ZX_OK, std::move(node_info));
    request = sender.TakeChannel();
  }
  if (connector_ == nullptr) {
    SendOnOpenEventOnError(flags, std::move(request), ZX_ERR_NOT_SUPPORTED);
    return ZX_ERR_NOT_SUPPORTED;
  }
  connector_(std::move(request), dispatcher);
  return ZX_OK;
}

zx_status_t Service::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
  out_attributes->mode = fuchsia::io::MODE_TYPE_SERVICE | V_IRUSR;
  out_attributes->id = fuchsia::io::INO_UNKNOWN;
  out_attributes->content_size = 0;
  out_attributes->storage_size = 0;
  out_attributes->link_count = 1;
  out_attributes->creation_time = 0;
  out_attributes->modification_time = 0;
  return ZX_OK;
}

NodeKind::Type Service::GetKind() const {
  return NodeKind::kService | NodeKind::kReadable | NodeKind::kWritable;
}

}  // namespace vfs
