// Copyright 2019 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 "smbfs/inode_map.h"

#include <utility>

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

namespace smbfs {

struct InodeMap::Entry {
  Entry(ino_t inode, const base::FilePath& path) : inode(inode), path(path) {}
  ~Entry() = default;

  uint64_t refcount = 0;

  const ino_t inode;
  base::FilePath path;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(Entry);
};

InodeMap::InodeMap(ino_t root_inode)
    : root_inode_(root_inode), seq_num_(root_inode + 1) {
  DCHECK(root_inode_);

  // Insert an entry for the root inode.
  std::unique_ptr<Entry> entry =
      std::make_unique<Entry>(root_inode, base::FilePath("/"));
  entry->refcount = 1;
  files_.emplace("/", entry.get());
  inodes_.emplace(root_inode, std::move(entry));
}

InodeMap::~InodeMap() = default;

InodeMap::Entry* InodeMap::GetEntryByPath(const base::FilePath& path) {
  CHECK(!path.empty());
  CHECK(path.IsAbsolute());
  CHECK(!path.ReferencesParent());

  const auto it = files_.find(path.value());
  if (it != files_.end()) {
    return it->second;
  }

  DCHECK(!base::Contains(inodes_, seq_num_));

  ino_t inode = seq_num_++;
  CHECK(inode) << "Inode wrap around";
  std::unique_ptr<Entry> entry = std::make_unique<Entry>(inode, path);
  Entry* raw_entry = entry.get();
  files_.emplace(path.value(), raw_entry);
  inodes_.emplace(inode, std::move(entry));
  return raw_entry;
}

ino_t InodeMap::GetWeakInode(const base::FilePath& path) {
  Entry* entry = GetEntryByPath(path);
  return entry->inode;
}

ino_t InodeMap::IncInodeRef(const base::FilePath& path) {
  Entry* entry = GetEntryByPath(path);
  entry->refcount++;
  CHECK(entry->refcount) << "Refcount wrap around";
  return entry->inode;
}

base::FilePath InodeMap::GetPath(ino_t inode) const {
  const auto it = inodes_.find(inode);
  if (it == inodes_.end() || it->second->refcount == 0) {
    return {};
  }
  return it->second->path;
}

bool InodeMap::PathExists(const base::FilePath& path) const {
  auto it = files_.find(path.value());
  return it != files_.end() && it->second->refcount > 0;
}

void InodeMap::UpdatePath(ino_t inode, const base::FilePath& new_path) {
  CHECK_NE(inode, root_inode_);
  CHECK(!new_path.empty());
  CHECK(new_path.IsAbsolute());
  CHECK(!new_path.ReferencesParent());
  DCHECK(!PathExists(new_path));

  const auto it = inodes_.find(inode);
  CHECK(it != inodes_.end());
  CHECK_GT(it->second->refcount, 0);

  const base::FilePath old_path = it->second->path;
  it->second->path = new_path;

  files_.erase(old_path.value());
  files_.emplace(new_path.value(), it->second.get());
}

bool InodeMap::Forget(ino_t inode, uint64_t forget_count) {
  if (inode == root_inode_) {
    // Ignore the root inode.
    return false;
  }

  const auto it = inodes_.find(inode);
  CHECK(it != inodes_.end());

  Entry* entry = it->second.get();
  CHECK_GE(entry->refcount, forget_count);
  entry->refcount -= forget_count;
  if (entry->refcount > 0) {
    return false;
  }
  size_t removed = files_.erase(entry->path.value());
  DCHECK_EQ(removed, 1);
  inodes_.erase(it);
  return true;
}

}  // namespace smbfs
