// 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/vfs/cpp/connection.h>
#include <lib/vfs/cpp/flags.h>
#include <lib/vfs/cpp/node.h>

namespace vfs {

Connection::Connection(uint32_t flags) : flags_(flags) {}

Connection::~Connection() = default;

void Connection::Clone(Node* vn, uint32_t flags, zx::channel request,
                       async_dispatcher_t* dispatcher) {
  vn->Clone(flags, flags_, std::move(request), dispatcher);
}

void Connection::Close(Node* vn, fuchsia::io::Node::CloseCallback callback) {
  callback(ZX_OK);
  vn->Close(this);
  // |this| is destroyed at this point.
}

void Connection::Describe(Node* vn,
                          fuchsia::io::Node::DescribeCallback callback) {
  fuchsia::io::NodeInfo info{};
  vn->Describe(&info);
  if (info.has_invalid_tag()) {
    vn->Close(this);
  } else {
    callback(std::move(info));
  }
}

zx_status_t Connection::Bind(zx::channel request,
                             async_dispatcher_t* dispatcher) {
  auto status = BindInternal(std::move(request), dispatcher);
  if (status == ZX_OK && Flags::ShouldDescribe(flags_)) {
    SendOnOpenEvent(status);
  }  // can't send status as binding failed and request object is gone.
  return status;
}

void Connection::Sync(Node* vn, fuchsia::io::Node::SyncCallback callback) {
  // TODO: Check flags.
  callback(vn->Sync());
}

void Connection::GetAttr(Node* vn,
                         fuchsia::io::Node::GetAttrCallback callback) {
  // TODO: Check flags.
  fuchsia::io::NodeAttributes attributes{};
  zx_status_t status = vn->GetAttr(&attributes);
  callback(status, attributes);
}

void Connection::SetAttr(Node* vn, uint32_t flags,
                         fuchsia::io::NodeAttributes attributes,
                         fuchsia::io::Node::SetAttrCallback callback) {
  // TODO: Check flags.
  callback(vn->SetAttr(flags, attributes));
}

void Connection::Ioctl(Node* vn, uint32_t opcode, uint64_t max_out,
                       std::vector<zx::handle> handles, std::vector<uint8_t> in,
                       fuchsia::io::Node::IoctlCallback callback) {
  callback(ZX_ERR_NOT_SUPPORTED, std::vector<zx::handle>(),
           std::vector<uint8_t>());
}

std::unique_ptr<fuchsia::io::NodeInfo> Connection::NodeInfoIfStatusOk(
    Node* vn, zx_status_t status) {
  std::unique_ptr<fuchsia::io::NodeInfo> node_info;
  if (status == ZX_OK) {
    node_info = std::make_unique<fuchsia::io::NodeInfo>();
    vn->Describe(node_info.get());
  }
  return node_info;
}

}  // namespace vfs
