// Copyright 2021 The Chromium OS 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 "fusebox/fuse_path_inodes.h"

#include <vector>

#include <base/check.h>
#include <base/check_op.h>
#include <base/containers/contains.h>
#include <base/logging.h>
#include <base/strings/string_piece.h>

namespace {

std::string GetParentChildName(const char* path) {
  base::StringPiece name(path ? path : ".");

  if (name.empty() || name == "/")
    return path;
  if (name == "." || name == "..")
    return {};
  if (name.find('/') != base::StringPiece::npos)
    return {};

  return std::string("/").append(name.data(), name.size());
}

using Node = fusebox::Node;

inline Node* NodeError(int error) {
  errno = error;
  return nullptr;
}

Node* CreateNode(ino_t parent, const std::string& child, ino_t ino) {
  Node* node = new Node();
  CHECK(node);
  node->device = 0;
  node->parent = parent;
  node->ino = ino;
  node->name = child;
  node->refcount = 1;
  return node;
}

}  // namespace

namespace fusebox {

InodeTable::InodeTable() : ino_(0), stat_cache_(1024) {
  root_node_ = InsertNode(CreateNode(0, "/", CreateIno()));
}

ino_t InodeTable::CreateIno() {
  ino_t ino = ++ino_;
  CHECK(ino) << "inodes wrapped";
  return ino;
}

Node* InodeTable::Create(ino_t parent, const char* name) {
  std::string child = GetParentChildName(name);
  if (child.empty() || !parent)
    return NodeError(EINVAL);

  auto p = parent_map_.find(std::to_string(parent).append(child));
  if (p != parent_map_.end())
    return NodeError(EEXIST);

  return InsertNode(CreateNode(parent, child, CreateIno()));
}

Node* InodeTable::Lookup(ino_t ino, uint64_t ref) {
  auto n = node_map_.find(ino);
  if (n == node_map_.end())
    return NodeError(ENOENT);

  Node* node = n->second.get();
  node->refcount += ref;
  return node;
}

Node* InodeTable::Lookup(ino_t parent, const char* name, uint64_t ref) {
  std::string child = GetParentChildName(name);
  if (child.empty())
    return NodeError(EINVAL);

  auto p = parent_map_.find(std::to_string(parent).append(child));
  if (p == parent_map_.end())
    return NodeError(ENOENT);

  Node* node = p->second;
  node->refcount += ref;
  return node;
}

Node* InodeTable::Move(Node* node, ino_t parent, const char* name) {
  CHECK_NE(node, root_node_);

  if (node_map_.find(parent) == node_map_.end())
    return NodeError(EINVAL);

  std::string child = GetParentChildName(name);
  if (child.empty() || !node || node->ino == parent)
    return NodeError(EINVAL);

  auto p = parent_map_.find(std::to_string(parent).append(child));
  if (p != parent_map_.end())
    return NodeError(EEXIST);

  RemoveNode(node);
  node->parent = parent;
  node->name = child;
  return InsertNode(node);
}

bool InodeTable::Forget(ino_t ino, uint64_t nlookup) {
  if (!ino || ino == root_node_->ino)
    return false;  // Ignore root node.

  Node* node = Lookup(ino);
  if (!node)
    return true;

  if (nlookup < node->refcount) {
    node->refcount -= nlookup;
    return false;
  }

  delete RemoveNode(node);
  ForgetStat(ino);
  return true;
}

std::string InodeTable::GetName(ino_t ino) {
  if (Node* node = Lookup(ino))
    return node->name;
  return {};
}

std::string InodeTable::GetPath(Node* node) {
  DCHECK(node);

  std::vector<std::string> names;
  while (node->ino && node->parent) {
    names.push_back(node->name);
    auto parent = node_map_.find(node->parent);
    CHECK(parent != node_map_.end());
    node = parent->second.get();
  }

  std::string path;
  for (auto it = names.rbegin(); it != names.rend(); ++it)
    path.append(it->data(), it->size());
  if (path.empty())
    path.push_back('/');

  return path;
}

void InodeTable::SetStat(ino_t ino, struct stat stat, double timeout) {
  DCHECK(ino);
  stat.st_ino = ino;

  struct Stat item;
  item.time = timeout ? std::time(nullptr) + time_t(timeout) : time_t(0);
  item.stat = stat;

  stat_cache_.Put(stat.st_ino, item);
}

bool InodeTable::GetStat(ino_t ino, struct stat* stat) {
  DCHECK(stat);

  auto it = stat_cache_.Get(ino);
  if (it == stat_cache_.end())
    return false;

  const auto& item = it->second;
  if (item.time && item.time < std::time(nullptr)) {
    stat_cache_.Erase(it);  // stat time out
    return false;
  }

  *stat = item.stat;
  return true;
}

void InodeTable::ForgetStat(ino_t ino) {
  auto it = stat_cache_.Peek(ino);
  if (it != stat_cache_.end())
    stat_cache_.Erase(it);
}

Node* InodeTable::InsertNode(Node* node) {
  DCHECK(node);
  DCHECK(node->ino);

  CHECK_NE(node->parent, node->ino);
  parent_map_[std::to_string(node->parent).append(node->name)] = node;
  CHECK(!base::Contains(node_map_, node->ino));
  node_map_[node->ino].reset(node);

  return node;
}

Node* InodeTable::RemoveNode(Node* node) {
  DCHECK(node);

  parent_map_.erase(std::to_string(node->parent).append(node->name));
  auto n = node_map_.find(node->ino);
  CHECK(n != node_map_.end());
  n->second.release();
  node_map_.erase(n);

  return node;
}

}  // namespace fusebox
