// Copyright 2021 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 <string.h>

#include "f2fs.h"

namespace f2fs {

zx_status_t Dir::NewInode(uint32_t mode, fbl::RefPtr<VnodeF2fs> *out) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  nid_t ino;
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  VnodeF2fs *vnode = nullptr;

  do {
    fs::SharedLock rlock(sbi.fs_lock[static_cast<int>(LockType::kNodeNew)]);
    if (!Vfs()->Nodemgr().AllocNid(&ino)) {
      Iput(vnode);
      return ZX_ERR_NO_SPACE;
    }
  } while (false);

  VnodeF2fs::Allocate(Vfs(), ino, mode, &vnode_refptr);

  vnode = vnode_refptr.get();

  vnode->SetUid(getuid());

  if (HasGid()) {
    vnode->SetGid(GetGid());
    if (S_ISDIR(mode))
      mode |= S_ISGID;
  } else {
    vnode->SetGid(getgid());
  }

  vnode->SetMode(mode);
  vnode->InitSize();
  vnode->ClearNlink();
  vnode->InitBlocks();

  timespec cur_time;
  clock_gettime(CLOCK_REALTIME, &cur_time);
  vnode->SetATime(cur_time);
  vnode->SetCTime(cur_time);
  vnode->SetMTime(cur_time);
  vnode->SetGeneration(sbi.s_next_generation++);

  if (TestOpt(&sbi, kMountInlineDentry) && vnode->IsDir())
    vnode->SetFlag(InodeInfoFlag::kInlineDentry);

  vnode->SetFlag(InodeInfoFlag::kNewInode);
  Vfs()->InsertVnode(vnode);
  vnode->MarkInodeDirty();

  *out = std::move(vnode_refptr);
  return ZX_OK;
}

int Dir::IsMultimediaFile(const char *s, const char *sub) {
  int slen = strlen(s);
  int sublen = strlen(sub);
  int ret;

  if (sublen > slen)
    return 1;

  if (ret = memcmp(s + slen - sublen, sub, sublen); ret != 0) { /* compare upper case */
    int i;
    char upper_sub[8];
    for (i = 0; i < sublen && i < static_cast<int>(sizeof(upper_sub)); i++)
      upper_sub[i] = toupper(sub[i]);
    return memcmp(s + slen - sublen, upper_sub, sublen);
  }

  return ret;
}

/**
 * Set multimedia files as cold files for hot/cold data separation
 */
inline void Dir::SetColdFile(const char *name, VnodeF2fs *vnode) {
  int i;
  uint8_t(*extlist)[8] = Vfs()->RawSb().extension_list;

  int count = LeToCpu(Vfs()->RawSb().extension_count);
  for (i = 0; i < count; i++) {
    if (!IsMultimediaFile(name, reinterpret_cast<const char *>(extlist[i]))) {
      vnode->SetAdvise(FAdvise::kCold);
      break;
    }
  }
}

zx_status_t Dir::DoCreate(std::string_view name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  VnodeF2fs *vnode = nullptr;

  if (zx_status_t err = NewInode(S_IFREG | mode, &vnode_refptr); err != ZX_OK)
    return err;
  vnode = vnode_refptr.get();

  vnode->SetName(name);

  if (!TestOpt(&sbi, kMountDisableExtIdentify))
    SetColdFile(name.data(), vnode);

  vnode->SetFlag(InodeInfoFlag::kIncLink);
  if (zx_status_t err = AddLink(name, vnode); err != ZX_OK) {
    vnode->ClearNlink();
    vnode->UnlockNewInode();
    Iput(vnode);
    Vfs()->Nodemgr().AllocNidFailed(vnode->Ino());
    return err;
  }

  Vfs()->Nodemgr().AllocNidDone(vnode->Ino());

#if 0  // porting needed
  // if (!sbi.por_doing)
  //   d_instantiate(dentry, inode);
#endif
  vnode->UnlockNewInode();

  Vfs()->Segmgr().BalanceFs();

  *out = std::move(vnode_refptr);
  return ZX_OK;
}

zx_status_t Dir::Link(std::string_view name, fbl::RefPtr<fs::Vnode> _target) {
  VnodeF2fs *target = static_cast<VnodeF2fs *>(_target.get());

  if (target->IsDir())
    return ZX_ERR_NOT_FILE;

  Page *old_entry_page;
  DirEntry *old_entry = FindEntry(name, &old_entry_page);
  if (old_entry != nullptr) {
    nid_t old_ino = LeToCpu(old_entry->ino);
    if (old_ino == target->Ino())
      return ZX_ERR_ALREADY_EXISTS;
  }

  timespec cur_time;
  clock_gettime(CLOCK_REALTIME, &cur_time);
  target->SetCTime(cur_time);

#if 0  // porting needed
  // AtomicInc(&inode->i_count);
#endif

  target->SetFlag(InodeInfoFlag::kIncLink);
  if (zx_status_t err = AddLink(name, target); err != ZX_OK) {
    target->ClearFlag(InodeInfoFlag::kIncLink);
    Iput(target);
    return err;
  }

#if 0  // porting needed
  // d_instantiate(dentry, inode);
#endif

  Vfs()->Segmgr().BalanceFs();

  return ZX_OK;
}

#if 0  // porting needed
// dentry *Dir::F2fsGetParent(dentry *child) {
//   return nullptr;
//   // qstr dotdot = QSTR_INIT("..", 2);
//   // uint64_t ino = Inode_by_name(child->d_inode, &dotdot);
//   // if (!ino)
//   //   return ErrPtr(-ENOENT);
//   // return d_obtain_alias(f2fs_iget(child->d_inode->i_sb, ino));
// }
#endif

zx_status_t Dir::DoLookup(std::string_view name, fbl::RefPtr<fs::Vnode> *out) {
  fbl::RefPtr<VnodeF2fs> vn;
  DirEntry *de;
  Page *page;

  if (name.length() > kMaxNameLen)
    return ZX_ERR_OUT_OF_RANGE;

  de = FindEntry(name, &page);
  if (de) {
    nid_t ino = LeToCpu(de->ino);
#if 0  // porting needed
    // if (!f2fs_has_inline_dentry(dir))
    //   kunmap(page);
#endif
    F2fsPutPage(page, 0);

    if (zx_status_t ret = VnodeF2fs::Vget(Vfs(), ino, &vn); ret != ZX_OK)
      return ret;

    *out = std::move(vn);

    return ZX_OK;
  }

  return ZX_ERR_NOT_FOUND;
}

zx_status_t Dir::Lookup(std::string_view name, fbl::RefPtr<fs::Vnode> *out) {
  return DoLookup(name, out);
}

zx_status_t Dir::DoUnlink(VnodeF2fs *vnode, std::string_view name) {
  DirEntry *de;
  Page *page;

  de = FindEntry(name, &page);
  if (de == nullptr) {
    return ZX_ERR_NOT_FOUND;
  }

  if (zx_status_t err = Vfs()->CheckOrphanSpace(); err != ZX_OK) {
#if 0  // porting needed
    // if (!f2fs_has_inline_dentry(dir))
    //   kunmap(page);
#endif
    F2fsPutPage(page, 0);
    return err;
  }

  DeleteEntry(de, page, vnode);

  Vfs()->Segmgr().BalanceFs();

  return ZX_OK;
}

#if 0  // porting needed
// int Dir::F2fsSymlink(dentry *dentry, const char *symname) {
//   return 0;
//   //   fbl::RefPtr<VnodeF2fs> vnode_refptr;
//   //   VnodeF2fs *vnode = nullptr;
//   //   unsigned symlen = strlen(symname) + 1;
//   //   int err;

//   //   err = NewInode(S_IFLNK | S_IRWXUGO, &vnode_refptr);
//   //   if (err)
//   //     return err;
//   //   vnode = vnode_refptr.get();

//   //   // inode->i_mapping->a_ops = &f2fs_dblock_aops;

//   //   // err = AddLink(dentry, vnode);
//   //   if (err)
//   //     goto out;

//   //   err = page_symlink(vnode, symname, symlen);
//   //   Vfs()->Nodemgr().AllocNidDone(vnode->Ino());

//   //   // d_instantiate(dentry, vnode);
//   //   UnlockNewInode(vnode);

//   //   Vfs()->Segmgr().BalanceFs();

//   //   return err;
//   // out:
//   //   vnode->ClearNlink();
//   //   UnlockNewInode(vnode);
//   //   // Iput(inode);
//   //   Vfs()->Nodemgr().AllocNidFailed(vnode->Ino());
//   //   return err;
// }
#endif

zx_status_t Dir::Mkdir(std::string_view name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) {
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  VnodeF2fs *vnode = nullptr;

  if (zx_status_t err = NewInode(S_IFDIR | mode, &vnode_refptr); err != ZX_OK)
    return err;
  vnode = vnode_refptr.get();

  vnode->SetName(name);

#if 0  // porting needed
  // mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS | __GFP_ZERO);
#endif

  vnode->SetFlag(InodeInfoFlag::kIncLink);
  if (zx_status_t err = AddLink(name, vnode); err != ZX_OK) {
    vnode->ClearFlag(InodeInfoFlag::kIncLink);
    vnode->ClearNlink();
    vnode->UnlockNewInode();
    Iput(vnode);
    Vfs()->Nodemgr().AllocNidFailed(vnode->Ino());
    return err;
  }

  Vfs()->Nodemgr().AllocNidDone(vnode->Ino());

#if 0  // porting needed
  // d_instantiate(dentry, inode);
#endif
  vnode->UnlockNewInode();

  Vfs()->Segmgr().BalanceFs();

  *out = std::move(vnode_refptr);
  return ZX_OK;
}

zx_status_t Dir::Rmdir(Dir *vnode, std::string_view name) {
  if (vnode->IsEmptyDir())
    return DoUnlink(vnode, name);
  return ZX_ERR_NOT_EMPTY;
}

#if 0  // porting needed
// int Dir::F2fsMknod(dentry *dentry, umode_t mode, dev_t rdev) {
//   fbl::RefPtr<VnodeF2fs> vnode_refptr;
//   VnodeF2fs *vnode = nullptr;
//   int err = 0;

//   // if (!new_valid_dev(rdev))
//   //   return -EINVAL;

//   err = NewInode(mode, &vnode_refptr);
//   if (err)
//     return err;
//   vnode = vnode_refptr.get();

//   // init_special_inode(inode, inode->i_mode, rdev);
//   // inode->i_op = &f2fs_special_inode_operations;

//   // err = AddLink(dentry, vnode);
//   if (err)
//     goto out;

//   Vfs()->Nodemgr().AllocNidDone(vnode->Ino());
//   // d_instantiate(dentry, inode);
//   UnlockNewInode(vnode);

//   Vfs()->Segmgr().BalanceFs();

//   return 0;
// out:
//   vnode->ClearNlink();
//   UnlockNewInode(vnode);
//   Iput(vnode);
//   Vfs()->Nodemgr().AllocNidFailed(vnode->Ino());
//   return err;
// }
#endif

zx::status<bool> Dir::IsSubdir(Dir *possible_dir) {
  Dir *vn = possible_dir;
  fbl::RefPtr<VnodeF2fs> parent = nullptr;

  while (vn->Ino() != RootIno(&Vfs()->GetSbInfo())) {
    if (vn->Ino() == Ino()) {
      return zx::ok(true);
    }

    if (zx_status_t status = VnodeF2fs::Vget(Vfs(), vn->GetParentNid(), &parent); status != ZX_OK) {
      return zx::error(status);
    }

    vn = static_cast<Dir *>(parent.get());
  }
  return zx::ok(false);
}

zx_status_t Dir::Rename(fbl::RefPtr<fs::Vnode> _newdir, std::string_view oldname,
                        std::string_view newname, bool src_must_be_dir, bool dst_must_be_dir) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  fbl::RefPtr<VnodeF2fs> old_vn_ref;
  fbl::RefPtr<VnodeF2fs> new_vn_ref;
  Dir *old_dir = this;
  Dir *new_dir = static_cast<Dir *>(_newdir.get());
  VnodeF2fs *old_vnode;
  nid_t old_ino;
  VnodeF2fs *new_vnode;
  nid_t new_ino;
  Page *old_dir_page;
  Page *old_page;
  Page *new_page;
  DirEntry *old_dir_entry = nullptr;
  DirEntry *old_entry;
  DirEntry *new_entry;
  timespec cur_time;

  clock_gettime(CLOCK_REALTIME, &cur_time);

  if (new_dir->GetNlink() == 0)
    return ZX_ERR_NOT_FOUND;

  old_entry = FindEntry(oldname, &old_page);
  if (!old_entry) {
    return ZX_ERR_NOT_FOUND;
  }

  old_ino = LeToCpu(old_entry->ino);
  if (zx_status_t err = VnodeF2fs::Vget(Vfs(), old_ino, &old_vn_ref); err != ZX_OK) {
    return err;
  }

  old_vnode = old_vn_ref.get();
  ZX_ASSERT(old_vnode->IsSameName(oldname));

  if (!old_vnode->IsDir() && (src_must_be_dir || dst_must_be_dir))
    return ZX_ERR_NOT_DIR;

  ZX_ASSERT(!src_must_be_dir || old_vnode->IsDir());

  if (old_vnode->IsDir()) {
    old_dir_entry = (static_cast<Dir *>(old_vnode))->ParentDir(&old_dir_page);
    if (!old_dir_entry) {
#if 0  // porting needed
      // if (!f2fs_has_inline_dentry(old_dir))
      //   kunmap(old_page);
#endif
      F2fsPutPage(old_page, 0);

      return ZX_ERR_IO;
    }

    auto is_subdir = (static_cast<Dir *>(old_vnode))->IsSubdir(new_dir);
    if (is_subdir.is_error())
      return is_subdir.error_value();
    if (*is_subdir)
      return ZX_ERR_INVALID_ARGS;
  }

  do {
    fs::SharedLock rlock(sbi.fs_lock[static_cast<int>(LockType::kRename)]);

    new_entry = new_dir->FindEntry(newname, &new_page);
    if (new_entry) {
      new_ino = LeToCpu(new_entry->ino);
      if (zx_status_t err = VnodeF2fs::Vget(Vfs(), new_ino, &new_vn_ref); err != ZX_OK) {
        if (old_dir_entry) {
#if 0  // porting needed
       // if (!f2fs_has_inline_dentry(old_inode))
       //   kunmap(old_dir_page);
#endif
          F2fsPutPage(old_dir_page, 0);
        }

#if 0  // porting needed
      // if (!f2fs_has_inline_dentry(old_dir))
      //   kunmap(old_page);
#endif
        F2fsPutPage(old_page, 0);

        return err;
      }

      new_vnode = new_vn_ref.get();
      ZX_ASSERT(new_vnode->IsSameName(newname));

      if (!new_vnode->IsDir() && (src_must_be_dir || dst_must_be_dir))
        return ZX_ERR_NOT_DIR;

      if (old_vnode->IsDir() && !new_vnode->IsDir())
        return ZX_ERR_NOT_DIR;

      if (!old_vnode->IsDir() && new_vnode->IsDir())
        return ZX_ERR_NOT_FILE;

      if (old_dir == new_dir && oldname == newname)
        return ZX_OK;

      if (old_dir_entry &&
          (!new_vnode->IsDir() || !(static_cast<Dir *>(new_vnode))->IsEmptyDir())) {
#if 0  // porting needed
       // if (!f2fs_has_inline_dentry(old_inode))
       //   kunmap(old_dir_page);
#endif
        F2fsPutPage(old_dir_page, 0);

#if 0  // porting needed
      // if (!f2fs_has_inline_dentry(old_dir))
      //   kunmap(old_page);
#endif
        F2fsPutPage(old_page, 0);

        return ZX_ERR_NOT_EMPTY;
      }

      old_vnode->SetName(newname);
      new_dir->SetLink(new_entry, new_page, old_vnode);

      new_vnode->SetCTime(cur_time);
      if (old_dir_entry)
        new_vnode->DropNlink();
      new_vnode->DropNlink();
      if (!new_vnode->GetNlink())
        Vfs()->AddOrphanInode(new_vnode);
      new_vnode->WriteInode(NULL);
    } else {
      if (old_dir == new_dir && oldname == newname)
        return ZX_OK;

      old_vnode->SetName(newname);
      if (zx_status_t err = new_dir->AddLink(newname, old_vnode); err != ZX_OK) {
        if (old_dir_entry) {
#if 0  // porting needed
       // if (!f2fs_has_inline_dentry(old_inode))
       //   kunmap(old_dir_page);
#endif
          F2fsPutPage(old_dir_page, 0);
        }

#if 0  // porting needed
      // if (!f2fs_has_inline_dentry(old_dir))
      //   kunmap(old_page);
#endif
        F2fsPutPage(old_page, 0);

        return err;
      }

      if (old_dir_entry) {
        new_dir->IncNlink();
        new_dir->WriteInode(NULL);
      }
    }

    old_vnode->SetCTime(cur_time);
    old_vnode->SetFlag(InodeInfoFlag::kNeedCp);
    old_vnode->MarkInodeDirty();

    // TODO(djkim): remove this after pager is available
    // If old_dir == new_dir, old_page is not up-to-date after add new entry with newname
    // Therefore, old_page should be read again, unless pager is implemented
    if (old_dir == new_dir)
      old_entry = FindEntry(oldname, &old_page);

    DeleteEntry(old_entry, old_page, NULL);

    if (old_dir_entry) {
      if (old_dir != new_dir) {
        (static_cast<Dir *>(old_vnode))->SetLink(old_dir_entry, old_dir_page, new_dir);
      } else {
#if 0  // porting needed
       // if (!f2fs_has_inline_dentry(old_inode))
       //   kunmap(old_dir_page);
#endif
        F2fsPutPage(old_dir_page, 0);
      }
      old_dir->DropNlink();
      old_dir->WriteInode(NULL);
    }
  } while (false);

  Vfs()->Segmgr().BalanceFs();
  return ZX_OK;
}

zx_status_t Dir::Create(std::string_view name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) {
  Page *page;
  zx_status_t status = ZX_OK;

  if (GetNlink() == 0)
    return ZX_ERR_NOT_FOUND;

  if (FindEntry(name, &page) != nullptr) {
    return ZX_ERR_ALREADY_EXISTS;
  }

  if (S_ISDIR(mode)) {
    status = Mkdir(name, mode, out);
  } else {
    status = DoCreate(name, mode, out);
  }

  if (status != ZX_OK)
    return status;

  status = (*out)->OpenValidating(fs::VnodeConnectionOptions(), nullptr);
  return status;
}

zx_status_t Dir::Unlink(std::string_view name, bool must_be_dir) {
  fbl::RefPtr<fs::Vnode> vn;

  if (DoLookup(name, &vn) != ZX_OK) {
    return ZX_ERR_NOT_FOUND;
  }

  VnodeF2fs *vnode = (VnodeF2fs *)vn.get();

  if (vnode->IsDir())
    return Rmdir(static_cast<Dir *>(vnode), name);

  if (must_be_dir)
    return ZX_ERR_NOT_DIR;

  return DoUnlink(vnode, name);
}

}  // namespace f2fs
