// Copyright 2021 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/driver2/devfs_exporter.h>
#include <lib/fpromise/bridge.h>

namespace fdfs = fuchsia_device_fs;

namespace driver {

namespace {

fpromise::promise<void, zx_status_t> CheckFileExists(
    const fidl::WireSharedClient<fuchsia_io::Directory>& dir, std::string_view path,
    async_dispatcher_t* dispatcher) {
  auto svc_endpoints = fidl::CreateEndpoints<fuchsia_io::Node>();
  if (svc_endpoints.is_error()) {
    return fpromise::make_error_promise(svc_endpoints.status_value());
  }
  auto result = dir->Open(fuchsia_io::wire::OpenFlags::kNodeReference, 0,
                          fidl::StringView::FromExternal(path), std::move(svc_endpoints->server));
  if (!result.ok()) {
    return fpromise::make_error_promise(result.status());
  }
  auto file =
      fidl::WireSharedClient<fuchsia_io::Node>(std::move(svc_endpoints->client), dispatcher);

  // Call something simple on the Node to make sure we actually opened it successfully.
  // Otherwise, the open call is pipelined and it could fail silently.
  fpromise::bridge<void, zx_status_t> bridge;
  file->GetFlags().ThenExactlyOnce(
      [file = file.Clone(), completer = std::move(bridge.completer)](
          fidl::WireUnownedResult<fuchsia_io::Node::GetFlags>& result) mutable {
        if (result.ok()) {
          completer.complete_ok();
        } else {
          zx_status_t status = result.status();
          if (status == ZX_ERR_PEER_CLOSED) {
            status = ZX_ERR_NOT_FOUND;
          }
          completer.complete_error(status);
        }
      });
  return bridge.consumer.promise();
}

}  // namespace

zx::status<DevfsExporter> DevfsExporter::Create(
    const Namespace& ns, async_dispatcher_t* dispatcher,
    fidl::WireSharedClient<fuchsia_io::Directory> svc_dir) {
  auto result = ns.Connect<fdfs::Exporter>();
  if (result.is_error()) {
    return result.take_error();
  }
  fidl::WireSharedClient<fdfs::Exporter> client(std::move(*result), dispatcher);
  return zx::ok(DevfsExporter(dispatcher, std::move(client), std::move(svc_dir)));
}

DevfsExporter::DevfsExporter(async_dispatcher_t* dispatcher,
                             fidl::WireSharedClient<fdfs::Exporter> exporter,
                             fidl::WireSharedClient<fuchsia_io::Directory> svc_dir)
    : dispatcher_(dispatcher), exporter_(std::move(exporter)), svc_dir_(std::move(svc_dir)) {}

fpromise::promise<void, zx_status_t> DevfsExporter::ExportImpl(std::string_view service_path,
                                                               std::string_view devfs_path,
                                                               uint32_t protocol_id) const {
  // Get a connection to svc_dir.
  auto svc_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
  if (svc_endpoints.is_error()) {
    return fpromise::make_error_promise(svc_endpoints.status_value());
  }

  auto result =
      svc_dir_->Clone(fuchsia_io::wire::OpenFlags::kCloneSameRights,
                      fidl::ServerEnd<fuchsia_io::Node>(svc_endpoints->server.TakeChannel()));
  if (!result.ok()) {
    return fpromise::make_error_promise(result.status());
  }

  // Call the Exporter function.
  fpromise::bridge<void, zx_status_t> bridge;
  auto callback = [completer = std::move(bridge.completer)](
                      fidl::WireUnownedResult<fdfs::Exporter::Export>& response) mutable {
    if (!response.ok()) {
      completer.complete_error(response.status());
    } else if (response->is_error()) {
      completer.complete_error(response->error_value());
    } else {
      completer.complete_ok();
    }
  };
  exporter_
      ->Export(std::move(svc_endpoints->client), fidl::StringView::FromExternal(service_path),
               fidl::StringView::FromExternal(devfs_path), protocol_id)
      .ThenExactlyOnce(std::move(callback));
  return bridge.consumer.promise_or(fpromise::error(ZX_ERR_INTERNAL));
}

fpromise::promise<void, zx_status_t> DevfsExporter::Export(std::string_view service_path,
                                                           std::string_view devfs_path,
                                                           uint32_t protocol_id) const {
  return CheckFileExists(svc_dir_, service_path, dispatcher_)
      .and_then([this, service_path = std::string(service_path),
                 devfs_path = std::string(devfs_path),
                 protocol_id]() { return ExportImpl(service_path, devfs_path, protocol_id); });
}

}  // namespace driver
