// 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 <base/stl_util.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->AsWeakPtr()) {}

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_(std::move(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() {
  const int32_t dir_id = std::exchange(dir_id_, -1);
  DCHECK_NE(-1, dir_id);

  if (!samba_interface_) {
    LOG(ERROR) << "Cannot close directory [" << dir_id
               << "]: Samba implementation already deleted";
    return;
  }

  const int32_t error = samba_interface_->CloseDirectory(dir_id);
  if (error != 0) {
    LOG(ERROR) << "Cannot close directory [" << dir_id
               << "]: " << GetErrorFromErrno(error);
  }
}

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) ||
      base::Contains(name, '/') || base::Contains(name, '\\')) {
    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) ||
      base::Contains(name, '/') || base::Contains(name, '\\')) {
    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
