// 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_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(fbl::StringPiece 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::kFiIncLink);
  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(fbl::StringPiece 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::kFiIncLink);
  if (zx_status_t err = AddLink(name, target); err != ZX_OK) {
    ClearInodeFlag(&target->fi_, InodeInfoFlag::kFiIncLink);
    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(fbl::StringPiece 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(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> *out) {
  fbl::AutoLock lock(&i_mutex_);
  return DoLookup(name, out);
}

zx_status_t Dir::DoUnlink(VnodeF2fs *vnode, fbl::StringPiece 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);

  /* 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(fbl::StringPiece 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::kFiIncLink);
  if (zx_status_t err = AddLink(name, vnode); err != ZX_OK) {
    ClearInodeFlag(&vnode->fi_, InodeInfoFlag::kFiIncLink);
    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, fbl::StringPiece 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, fbl::StringPiece oldname,
                        fbl::StringPiece 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;

  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;

  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::kFiNeedCp);
    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(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) {
  Page *page;
  fbl::AutoLock lock(&i_mutex_);

  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(fbl::StringPiece 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);

  return DoUnlink(vnode, name);
}

}  // namespace f2fs
