// Copyright 2018 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/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/vfs/cpp/composed_service_dir.h>
#include <zircon/status.h>

namespace vfs {

ComposedServiceDir::ComposedServiceDir()
    : root_(std::make_unique<vfs::PseudoDir>()) {}

ComposedServiceDir::~ComposedServiceDir() {}

void ComposedServiceDir::set_fallback(
    fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir) {
  fallback_dir_ = fallback_dir.TakeChannel();
}

void ComposedServiceDir::AddService(const std::string& service_name,
                                    std::unique_ptr<vfs::Service> service) {
  root_->AddEntry(service_name, std::move(service));
}

zx_status_t ComposedServiceDir::GetAttr(
    fuchsia::io::NodeAttributes* out_attributes) const {
  return root_->GetAttr(out_attributes);
}

zx_status_t ComposedServiceDir::Readdir(uint64_t offset, void* data,
                                        uint64_t len, uint64_t* out_offset,
                                        uint64_t* out_actual) {
  return root_->Readdir(offset, data, len, out_offset, out_actual);
}

zx_status_t ComposedServiceDir::Lookup(const std::string& name,
                                       vfs::internal::Node** out) const {
  zx_status_t status = root_->Lookup(name, out);
  if (status == ZX_OK) {
    return status;
  }
  if (fallback_dir_) {
    auto entry = fallback_services_.find(name);
    if (entry != fallback_services_.end()) {
      *out = entry->second.get();
    } else {
      auto service = std::make_unique<vfs::Service>(
          [name = std::string(name.data(), name.length()),
           dir = &fallback_dir_](zx::channel request,
                                 async_dispatcher_t* dispatcher) {
            fdio_service_connect_at(dir->get(), name.c_str(),
                                    request.release());
          });
      *out = service.get();
      fallback_services_[name] = std::move(service);
    }
  } else {
    return ZX_ERR_NOT_FOUND;
  }
  return ZX_OK;
}

}  // namespace vfs
