// 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;
  auto cur_time = time(nullptr);

  do {
    fbl::AutoLock lock(&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->i_uid_ = getuid();

  if (i_mode_ & S_ISGID) {
    vnode->i_gid_ = i_gid_;
    if (S_ISDIR(mode))
      mode |= S_ISGID;
  } else {
    vnode->i_gid_ = getgid();
  }

  vnode->i_mode_ = mode;
  vnode->i_size_ = 0;
  vnode->i_nlink_ = 0;
  vnode->i_blocks_ = 0;

  cur_time = time(nullptr);
  vnode->i_mtime_.tv_sec = cur_time;
  vnode->i_mtime_.tv_nsec = 0;
  vnode->i_atime_.tv_sec = cur_time;
  vnode->i_atime_.tv_nsec = 0;
  vnode->i_ctime_.tv_sec = cur_time;
  vnode->i_ctime_.tv_nsec = 0;

  vnode->i_generation_ = sbi.s_next_generation++;

  Vfs()->InsertVnode(vnode);

  MarkInodeDirty(vnode);
  *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) {
  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]))) {
      fi_.i_advise |= kFAdviseColdBit;
      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->i_name_sp_ = name;

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

  SetInodeFlag(&vnode->fi_, InodeInfoFlag::kIncLink);
  if (zx_status_t err = AddLink(name, vnode); err != ZX_OK) {
    vnode->ClearNlink();
    UnlockNewInode(vnode);
    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
  UnlockNewInode(vnode);

  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());
  auto cur_time = time(nullptr);

  fbl::AutoLock lock(&i_mutex_);
  fbl::AutoLock tlock(&target->i_mutex_);

  target->i_ctime_.tv_sec = cur_time;
  target->i_ctime_.tv_nsec = 0;

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

  SetInodeFlag(&target->fi_, InodeInfoFlag::kIncLink);
  if (zx_status_t err = AddLink(name, target); err != ZX_OK) {
    ClearInodeFlag(&target->fi_, 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
    // 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) {
  fbl::AutoLock lock(&i_mutex_);
  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
    // kunmap(page);
#endif
    F2fsPutPage(page, 0);
    return err;
  }

  DeleteEntry(de, page, vnode);

  vnode->ClearNlink();

  /* In order to evict this inode,  we set it dirty */
  MarkInodeDirty(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->i_name_sp_ = name;

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

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

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

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

  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_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;
  auto cur_time = time(nullptr);

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

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

  fbl::AutoLock lock(&i_mutex_);

  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();
  old_vnode->i_name_sp_ = oldname;

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

  ZX_ASSERT(!src_must_be_dir || S_ISDIR(old_vnode->i_mode_));

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

      return ZX_ERR_IO;
    }
  }

  do {
    fbl::AutoLock 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
       // kunmap(old_dir_page);
#endif
          F2fsPutPage(old_dir_page, 0);
        }

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

        return err;
      }

      new_vnode = new_vn_ref.get();
      new_vnode->i_name_sp_ = newname;

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

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

        return ZX_ERR_NOT_EMPTY;
      }

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

      cur_time = time(nullptr);
      new_vnode->i_ctime_.tv_sec = cur_time;
      new_vnode->i_ctime_.tv_nsec = 0;
      if (old_dir_entry)
        new_vnode->DropNlink();
      new_vnode->DropNlink();
      if (!new_vnode->i_nlink_)
        Vfs()->AddOrphanInode(new_vnode->Ino());
      new_vnode->WriteInode(NULL);
    } else {
      old_vnode->i_name_sp_ = newname;
      if (zx_status_t err = new_dir->AddLink(newname, old_vnode); err != ZX_OK) {
        if (old_dir_entry) {
#if 0  // porting needed
       // kunmap(old_dir_page);
#endif
          F2fsPutPage(old_dir_page, 0);
        }

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

        return err;
      }

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

    old_vnode->i_ctime_.tv_sec = cur_time;
    old_vnode->i_ctime_.tv_nsec = 0;
    SetInodeFlag(&old_vnode->fi_, InodeInfoFlag::kNeedCp);
    MarkInodeDirty(old_vnode);

    // 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
       // 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;
  fbl::AutoLock lock(&i_mutex_);

  if (i_nlink_ == 0)
    return ZX_ERR_NOT_FOUND;

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

  if (S_ISDIR(mode))
    return Mkdir(name, mode, out);

  return DoCreate(name, mode, out);
}

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

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

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

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

  if (must_be_dir)
    return ZX_ERR_NOT_DIR;

  return DoUnlink(vnode, name);
}

}  // namespace f2fs
