// 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 "local-vnode.h"

#include <lib/zx/channel.h>
#include <zircon/types.h>

#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/string.h>
#include <fbl/string_buffer.h>
#include <fbl/string_piece.h>

namespace fdio_internal {

fbl::RefPtr<LocalVnode> LocalVnode::Create(fbl::RefPtr<LocalVnode> parent, zx::channel remote,
                                           fbl::String name) {
  auto vn = fbl::AdoptRef(new LocalVnode(std::move(parent), std::move(remote), std::move(name)));
  if (vn->parent_ != nullptr) {
    vn->parent_->AddEntry(vn);
  }
  return vn;
}

void LocalVnode::AddEntry(fbl::RefPtr<LocalVnode> vn) {
  // |fdio_namespace| already checked that the entry does not exist.
  ZX_DEBUG_ASSERT(entries_by_name_.find(vn->name_) == entries_by_name_.end());

  auto entry = std::make_unique<Entry>(next_node_id_, std::move(vn));
  entries_by_name_.insert(entry.get());
  entries_by_id_.insert(std::move(entry));
  next_node_id_++;
}

void LocalVnode::RemoveEntry(LocalVnode* vn) {
  auto it = entries_by_name_.find(vn->Name());
  if (it != entries_by_name_.end() && it->node().get() == vn) {
    auto id = it->id();
    entries_by_name_.erase(it);
    entries_by_id_.erase(id);
  }
}

void LocalVnode::Unlink() {
  UnlinkChildren();
  UnlinkFromParent();
}

// Returns a child if it has the name |name|.
// Otherwise, returns nullptr.
fbl::RefPtr<LocalVnode> LocalVnode::Lookup(const fbl::StringPiece& name) const {
  auto it = entries_by_name_.find(name);
  if (it != entries_by_name_.end()) {
    return it->node();
  }
  return nullptr;
}

LocalVnode::LocalVnode(fbl::RefPtr<LocalVnode> parent, zx::channel remote, fbl::String name)
    : parent_(std::move(parent)), remote_(std::move(remote)), name_(std::move(name)) {}

void LocalVnode::UnlinkChildren() {
  for (auto& entry : entries_by_name_) {
    entry.node()->UnlinkChildren();
    entry.node()->parent_ = nullptr;
  }
  entries_by_name_.clear();
  entries_by_id_.clear();
}

void LocalVnode::UnlinkFromParent() {
  if (parent_) {
    parent_->RemoveEntry(this);
  }
  parent_ = nullptr;
}

zx_status_t EnumerateInternal(const LocalVnode& vn, fbl::StringBuffer<PATH_MAX>* path,
                              const EnumerateCallback& func) {
  size_t original_length = path->length();

  // Add this current node to the path, and enumerate it if it has a remote
  // object.
  path->Append(vn.Name().data(), vn.Name().length());
  if (vn.Remote().is_valid()) {
    func(fbl::StringPiece(path->data(), path->length()), vn.Remote());
  }

  // If we added a non-null path, add a separator and enumerate all the
  // children.
  if (vn.Name().length() > 0) {
    path->Append('/');
  }

  vn.ForAllChildren(
      [&path, &func](const LocalVnode& child) { return EnumerateInternal(child, path, func); });

  // To re-use the same prefix buffer, restore the original buffer length
  // after enumeration has completed.
  path->Resize(original_length);
  return ZX_OK;
}

zx_status_t EnumerateRemotes(const LocalVnode& vn, const EnumerateCallback& func) {
  fbl::StringBuffer<PATH_MAX> path;
  path.Append('/');
  return EnumerateInternal(vn, &path, func);
}

void LocalVnode::Readdir(uint64_t* last_seen, fbl::RefPtr<LocalVnode>* out_vnode) const {
  for (auto it = entries_by_id_.lower_bound(*last_seen); it != entries_by_id_.end(); ++it) {
    if (it->id() <= *last_seen) {
      continue;
    }
    *last_seen = it->id();
    *out_vnode = it->node();
    return;
  }
  *out_vnode = nullptr;
}

}  // namespace fdio_internal
