// 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::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(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::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(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::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, 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::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(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
