// 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) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  nid_t ino;
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  VnodeF2fs *vnode = nullptr;
  auto cur_time = time(nullptr);

  do {
    fbl::AutoLock lock(&sbi.fs_lock[NODE_NEW]);
    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 |= FADVISE_COLD_BIT;
      break;
    }
  }
}

zx_status_t Dir::DoCreate(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  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 (!test_opt(&sbi, DISABLE_EXT_IDENTIFY))
    SetColdFile(name.data());

  SetInodeFlag(&vnode->fi_, FI_INC_LINK);
  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().F2fsBalanceFs();

  *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_, FI_INC_LINK);
  if (zx_status_t err = AddLink(name, target); err != ZX_OK) {
    ClearInodeFlag(&target->fi_, FI_INC_LINK);
    Iput(target);
    return err;
  }

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

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

  return ZX_OK;
}

#if 0  // porting needed
// dentry *Dir::F2fsGetParent(dentry *child) {
//   return nullptr;
//   // qstr dotdot = QSTR_INIT("..", 2);
//   // uint64_t ino = f2fs_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;
  f2fs_dir_entry *de;
  Page *page;

  if (name.length() > F2FS_MAX_NAME_LEN)
    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) {
  f2fs_dir_entry *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().F2fsBalanceFs();

  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().F2fsBalanceFs();

//   //   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_, FI_INC_LINK);
  if (zx_status_t err = AddLink(name, vnode); err != ZX_OK) {
    ClearInodeFlag(&vnode->fi_, FI_INC_LINK);
    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().F2fsBalanceFs();

  *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().F2fsBalanceFs();

//   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) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  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;
  f2fs_dir_entry *old_dir_entry = nullptr;
  f2fs_dir_entry *old_entry;
  f2fs_dir_entry *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[RENAME]);

    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_, FI_NEED_CP);
    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().F2fsBalanceFs();
  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
