// Copyright 2020 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.

#ifndef LIB_DRIVER2_NAMESPACE_H_
#define LIB_DRIVER2_NAMESPACE_H_

#include <fidl/fuchsia.component.runner/cpp/wire.h>
#include <lib/fdio/namespace.h>

namespace driver {

namespace internal {

zx::status<> DirectoryOpenFunc(zx::unowned_channel dir, fidl::StringView path, zx::channel remote);

}  // namespace internal

// Manages a driver's namespace.
class Namespace {
 public:
  // Creates a namespace from `DriverStartArgs::ns`.
  static zx::status<Namespace> Create(
      fidl::VectorView<fuchsia_component_runner::wire::ComponentNamespaceEntry>& entries);

  Namespace() = default;
  ~Namespace();

  Namespace(Namespace&& other) noexcept;
  Namespace& operator=(Namespace&& other) noexcept;

  // Connect to a protocol within a driver's namespace.
  template <typename T>
  zx::status<fidl::ClientEnd<T>> Connect(
      std::string_view path = fidl::DiscoverableProtocolDefaultPath<T>,
      fuchsia_io::wire::OpenFlags flags = fuchsia_io::wire::OpenFlags::kRightReadable) const {
    auto endpoints = fidl::CreateEndpoints<T>();
    if (endpoints.is_error()) {
      return endpoints.take_error();
    }
    auto result = Connect(path, endpoints->server.TakeChannel(), flags);
    if (result.is_error()) {
      return result.take_error();
    }
    return zx::ok(std::move(endpoints->client));
  }

  // Connect to a service within a driver's namespace.
  template <typename FidlService>
  zx::status<typename FidlService::ServiceClient> OpenService(std::string_view instance) const {
    std::string path = std::string("/") + FidlService::Name + "/" + std::string(instance);
    auto result =
        Connect<fuchsia_io::Directory>(path, fuchsia_io::wire::OpenFlags::kRightReadable |
                                                 fuchsia_io::wire::OpenFlags::kRightWritable);
    if (result.is_error()) {
      return result.take_error();
    }

    return zx::ok(typename FidlService::ServiceClient(std::move(result.value().TakeChannel()),
                                                      internal::DirectoryOpenFunc));
  }

  zx::status<> Connect(
      std::string_view path, zx::channel server_end,
      fuchsia_io::wire::OpenFlags flags = fuchsia_io::wire::OpenFlags::kRightReadable |
                                          fuchsia_io::wire::OpenFlags::kRightWritable) const;

 private:
  explicit Namespace(fdio_ns_t* ns);

  Namespace(const Namespace& other) = delete;
  Namespace& operator=(const Namespace& other) = delete;

  fdio_ns_t* ns_ = nullptr;
};

}  // namespace driver

#endif  // LIB_DRIVER2_NAMESPACE_H_
