// Copyright 2018 The Chromium OS 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 "smbprovider/iterator/directory_iterator.h"

#include <utility>

#include <base/logging.h>

#include "smbprovider/constants.h"
#include "smbprovider/smbprovider_helper.h"

namespace smbprovider {
namespace {

constexpr int32_t kNoMoreEntriesError = -1;

}  // namespace

BaseDirectoryIterator::BaseDirectoryIterator(const std::string& dir_path,
                                             SambaInterface* samba_interface)
    : BaseDirectoryIterator(dir_path,
                            samba_interface,
                            kDefaultMetadataBatchSize,
                            false /* include_metadata */) {}

BaseDirectoryIterator::BaseDirectoryIterator(const std::string& dir_path,
                                             SambaInterface* samba_interface,
                                             size_t batch_size)
    : BaseDirectoryIterator(
          dir_path, samba_interface, batch_size, false /* include_metadata */) {
}

BaseDirectoryIterator::BaseDirectoryIterator(const std::string& dir_path,
                                             SambaInterface* samba_interface,
                                             size_t batch_size,
                                             bool include_metadata)
    : dir_path_(dir_path),
      batch_size_(batch_size),
      include_metadata_(include_metadata),
      samba_interface_(samba_interface) {}

BaseDirectoryIterator::BaseDirectoryIterator(BaseDirectoryIterator&& other)
    : dir_path_(std::move(other.dir_path_)),
      entries_(std::move(other.entries_)),
      current_entry_index_(other.current_entry_index_),
      batch_size_(other.batch_size_),
      dir_id_(other.dir_id_),
      is_done_(other.is_done_),
      is_initialized_(other.is_initialized_),
      include_metadata_(other.include_metadata_),
      samba_interface_(other.samba_interface_) {
  other.dir_id_ = -1;
  other.is_initialized_ = false;
  other.samba_interface_ = nullptr;
}

BaseDirectoryIterator::~BaseDirectoryIterator() {
  if (dir_id_ != -1) {
    CloseDirectory();
  }
}

int32_t BaseDirectoryIterator::Init() {
  DCHECK(!is_initialized_);

  int32_t open_dir_error = OpenDirectory();
  if (open_dir_error != 0) {
    return open_dir_error;
  }
  is_initialized_ = true;
  return Next();
}

int32_t BaseDirectoryIterator::Next() {
  DCHECK(is_initialized_);
  DCHECK(!is_done_);

  ++current_entry_index_;
  if (current_entry_index_ >= entries_.size()) {
    int32_t result = FillBuffer();
    if (result != 0 && result != kNoMoreEntriesError) {
      return result;
    }
  }
  return 0;
}

const DirectoryEntry& BaseDirectoryIterator::Get() {
  DCHECK(is_initialized_);
  DCHECK(!is_done_);
  DCHECK_LT(current_entry_index_, entries_.size());

  return entries_[current_entry_index_];
}

bool BaseDirectoryIterator::IsDone() {
  DCHECK(is_initialized_);
  return is_done_;
}

int32_t BaseDirectoryIterator::OpenDirectory() {
  DCHECK_EQ(-1, dir_id_);
  return samba_interface_->OpenDirectory(dir_path_, &dir_id_);
}

void BaseDirectoryIterator::CloseDirectory() {
  DCHECK_NE(-1, dir_id_);
  int32_t result = samba_interface_->CloseDirectory(dir_id_);
  if (result != 0) {
    LOG(ERROR) << "BaseDirectoryIterator: CloseDirectory failed with error: "
               << GetErrorFromErrno(result);
  }
  dir_id_ = -1;
}

int32_t BaseDirectoryIterator::FillBuffer() {
  int32_t fetch_error = include_metadata_ ? ReadEntriesWithMetadataToVector()
                                          : ReadEntriesToVector();

  if (fetch_error != 0) {
    return fetch_error;
  }

  if (entries_.empty()) {
    // Succeeded but nothing valid left to read.
    is_done_ = true;
    return kNoMoreEntriesError;
  }

  return 0;
}

int32_t BaseDirectoryIterator::ReadEntriesToVector() {
  DCHECK(!include_metadata_);
  DCHECK_GT(batch_size_, 0);

  ClearVector();

  for (size_t i = 0; i < batch_size_; i++) {
    const struct smbc_dirent* dirent = nullptr;
    int fetch_error = samba_interface_->GetDirectoryEntry(dir_id_, &dirent);
    if (fetch_error) {
      return fetch_error;
    }

    if (!dirent) {
      // There are no more files, but this is not an error. The next call to
      // refill the buffer will hit this case on the first iteration of the
      // loop and will return an empty vector which will cause FillBuffer()
      // to set |done_| and return |kNoMoreEntriesError|.
      return 0;
    }

    AddEntryIfValid(*dirent);
  }

  // Completed the batch successfully.
  return 0;
}

int32_t BaseDirectoryIterator::ReadEntriesWithMetadataToVector() {
  DCHECK(include_metadata_);
  DCHECK_GT(batch_size_, 0);

  ClearVector();

  for (size_t i = 0; i < batch_size_; i++) {
    const struct libsmb_file_info* file_info = nullptr;
    int fetch_error =
        samba_interface_->GetDirectoryEntryWithMetadata(dir_id_, &file_info);
    if (fetch_error) {
      return fetch_error;
    }

    if (!file_info) {
      // There are no more files, but this is not an error. The next call to
      // refill the buffer will hit this case on the first iteration of the
      // loop and will return an empty vector which will cause FillBuffer()
      // to set |done_| and return |kNoMoreEntriesError|.
      return 0;
    }

    AddEntryIfValid(*file_info);
  }

  // Completed the batch successfully.
  return 0;
}

void BaseDirectoryIterator::ClearVector() {
  entries_.clear();
  current_entry_index_ = 0;
}

void BaseDirectoryIterator::AddEntryIfValid(const smbc_dirent& dirent) {
  const std::string name(dirent.name);
  // Ignore "." and ".." entries.
  // TODO(allenvic): Handle SMBC_LINK
  if (IsSelfOrParentDir(name) || !ShouldIncludeEntryType(dirent.smbc_type)) {
    return;
  }

  bool is_directory =
      dirent.smbc_type == SMBC_DIR || dirent.smbc_type == SMBC_FILE_SHARE;
  entries_.emplace_back(is_directory, name, AppendPath(dir_path_, name));
}

void BaseDirectoryIterator::AddEntryIfValid(
    const struct libsmb_file_info& file_info) {
  const std::string name(file_info.name);
  const uint16_t attrs(file_info.attrs);
  // Ignore "." and ".." entries as well as symlinks.
  // TODO(zentaro): Investigate how this API deals with directories that are
  // file shares.
  if (IsSelfOrParentDir(name) || IsSymlink(file_info.attrs)) {
    return;
  }

  bool is_directory = attrs & kFileAttributeDirectory;
  entries_.emplace_back(is_directory, name, AppendPath(dir_path_, name),
                        file_info.size, file_info.mtime_ts.tv_sec);
}

}  // namespace smbprovider
