// Copyright 2017 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/smbprovider.h"

#include <algorithm>
#include <map>
#include <utility>

#include <base/files/file_path.h>
#include <base/memory/ptr_util.h>
#include <dbus/smbprovider/dbus-constants.h>

#include "smbprovider/constants.h"
#include "smbprovider/file_copy_progress.h"
#include "smbprovider/iterator/caching_iterator.h"
#include "smbprovider/iterator/directory_iterator.h"
#include "smbprovider/iterator/post_depth_first_iterator.h"
#include "smbprovider/mount_manager.h"
#include "smbprovider/netbios_packet_parser.h"
#include "smbprovider/proto.h"
#include "smbprovider/proto_bindings/directory_entry.pb.h"
#include "smbprovider/recursive_copy_progress.h"
#include "smbprovider/samba_interface.h"
#include "smbprovider/smbprovider_helper.h"

namespace smbprovider {

bool GetEntries(const ReadDirectoryOptionsProto& options,
                CachingIterator<DirectoryIterator> iterator,
                int32_t* error_code,
                ProtoBlob* out_entries) {
  DCHECK(error_code);
  DCHECK(out_entries);

  DirectoryEntryListProto directory_entries;

  int32_t result = iterator.Init();
  while (result == 0) {
    if (iterator.IsDone()) {
      *error_code = static_cast<int32_t>(
          SerializeProtoToBlob(directory_entries, out_entries));
      return true;
    }
    AddDirectoryEntry(iterator.Get(), &directory_entries);
    result = iterator.Next();
  }

  // The while-loop is only exited if there is an error. A full successful
  // execution will return from inside the above while-loop.
  *error_code = GetErrorFromErrno(result);
  LogOperationError(GetMethodName(options), GetMountId(options),
                    static_cast<ErrorType>(*error_code));
  return false;
}

bool GetShareEntries(const GetSharesOptionsProto& options,
                     ShareIterator iterator,
                     int32_t* error_code,
                     ProtoBlob* out_entries) {
  DCHECK(error_code);
  DCHECK(out_entries);

  DirectoryEntryListProto directory_entries;

  int32_t result = iterator.Init();
  while (result == 0) {
    if (iterator.IsDone()) {
      *error_code = static_cast<int32_t>(
          SerializeProtoToBlob(directory_entries, out_entries));
      return true;
    }
    AddDirectoryEntry(iterator.Get(), &directory_entries);
    result = iterator.Next();
  }

  // The while-loop is only exited if there is an error. A full successful
  // execution will return from inside the above while-loop.
  *error_code = GetErrorFromErrno(result);
  LogOperationError(GetMethodName(options), GetMountId(options),
                    static_cast<ErrorType>(*error_code));
  return false;
}

SmbProvider::SmbProvider(
    std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object,
    std::unique_ptr<MountManager> mount_manager,
    std::unique_ptr<KerberosArtifactSynchronizer> kerberos_synchronizer)
    : org::chromium::SmbProviderAdaptor(this),
      dbus_object_(std::move(dbus_object)),
      mount_manager_(std::move(mount_manager)),
      kerberos_synchronizer_(std::move(kerberos_synchronizer)) {}

void SmbProvider::RegisterAsync(
    const AsyncEventSequencer::CompletionAction& completion_callback) {
  RegisterWithDBusObject(dbus_object_.get());
  dbus_object_->RegisterAsync(completion_callback);
}

void SmbProvider::Mount(const ProtoBlob& options_blob,
                        const base::ScopedFD& password_fd,
                        int32_t* error_code,
                        int32_t* mount_id) {
  DCHECK(error_code);
  DCHECK(mount_id);
  *mount_id = -1;

  // The functions below will set the error if they fail.
  *error_code = static_cast<int32_t>(ERROR_OK);

  // AddMount() has to be called first since the credential has to be stored
  // before calling CanAccessMount().
  MountOptionsProto options;
  const bool success =
      ParseOptionsProto(options_blob, &options, error_code) &&
      AddMount(options.path(), options.workgroup(), options.username(),
               password_fd, error_code, mount_id) &&
      CanAccessMount(*mount_id, options.path(), error_code);

  if (!success) {
    // If AddMount() was successful but the mount could not be accessed, remove
    // the mount from mount_manager_.
    RemoveMountIfMounted(*mount_id);
  }
}

int32_t SmbProvider::Remount(const ProtoBlob& options_blob,
                             const base::ScopedFD& password_fd) {
  // The functions below will set the error if they fail.
  int32_t error_code = static_cast<int32_t>(ERROR_OK);

  RemountOptionsProto options;
  const bool remounted =
      ParseOptionsProto(options_blob, &options, &error_code) &&
      Remount(options.path(), GetMountId(options), options.workgroup(),
              options.username(), password_fd, &error_code);

  if (!remounted) {
    return error_code;
  }

  if (!CanAccessMount(GetMountId(options), options.path(), &error_code)) {
    RemoveMountIfMounted(GetMountId(options));
  }

  return error_code;
}

int32_t SmbProvider::Unmount(const ProtoBlob& options_blob) {
  int32_t error_code;
  UnmountOptionsProto options;
  if (!ParseOptionsProto(options_blob, &options, &error_code) ||
      !IsMounted(options, &error_code) ||
      !RemoveMount(GetMountId(options), &error_code)) {
    return error_code;
  }

  return ERROR_OK;
}

void SmbProvider::ReadDirectory(const ProtoBlob& options_blob,
                                int32_t* error_code,
                                ProtoBlob* out_entries) {
  DCHECK(error_code);
  DCHECK(out_entries);

  ReadDirectoryEntries(options_blob, error_code, out_entries);
}

void SmbProvider::ReadDirectoryEntries(const ProtoBlob& options_blob,
                                       int32_t* error_code,
                                       ProtoBlob* out_entries) {
  DCHECK(error_code);
  DCHECK(out_entries);
  out_entries->clear();

  std::string full_path;
  ReadDirectoryOptionsProto options;
  if (ParseOptionsAndPath(options_blob, &options, &full_path, error_code)) {
    MetadataCache* cache = nullptr;
    bool got_cache =
        mount_manager_->GetMetadataCache(GetMountId(options), &cache);
    DCHECK(got_cache);
    DCHECK(cache);

    SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
      // Purge the cache of expired entries before reading next directory.
    cache->PurgeExpiredEntries();
    GetEntries(options,
               GetCachingIterator<DirectoryIterator>(full_path, samba_interface,
                                                     cache),
               error_code, out_entries);
  }
}

void SmbProvider::ReadShareEntries(const ProtoBlob& options_blob,
                                   int32_t* error_code,
                                   ProtoBlob* out_entries) {
  DCHECK(error_code);
  DCHECK(out_entries);
  out_entries->clear();

  std::string full_path;
  GetSharesOptionsProto options;
  if (ParseOptionsAndPath(options_blob, &options, &full_path, error_code)) {
    SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));

    GetShareEntries(options,
                    GetIterator<ShareIterator>(full_path, samba_interface),
                    error_code, out_entries);
  }
}

void SmbProvider::GetMetadataEntry(const ProtoBlob& options_blob,
                                   int32_t* error_code,
                                   ProtoBlob* out_entry) {
  DCHECK(error_code);
  DCHECK(out_entry);
  out_entry->clear();

  std::string full_path;
  GetMetadataEntryOptionsProto options;
  if (!ParseOptionsAndPath(options_blob, &options, &full_path, error_code)) {
    return;
  }

  // If we have the result cached, then return it.
  if (GetCachedEntry(GetMountId(options), full_path, out_entry)) {
    *error_code = static_cast<int32_t>(ERROR_OK);
    return;
  }

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  struct stat stat_info;
  int32_t get_status_error =
      samba_interface->GetEntryStatus(full_path.c_str(), &stat_info);
  if (get_status_error != 0) {
    LogAndSetError(options, GetErrorFromErrno(get_status_error), error_code);
    return;
  }
  *error_code = GetDirectoryEntryProtoFromStat(full_path, stat_info, out_entry);
}

void SmbProvider::OpenFile(const ProtoBlob& options_blob,
                           int32_t* error_code,
                           int32_t* file_id) {
  DCHECK(error_code);
  DCHECK(file_id);

  std::string full_path;
  OpenFileOptionsProto options;
  if (!ParseOptionsAndPath(options_blob, &options, &full_path, error_code)) {
    return;
  }

  if (!OpenFile(options, full_path, error_code, file_id)) {
    *file_id = -1;
    return;
  }

  *error_code = static_cast<int32_t>(ERROR_OK);
}

int32_t SmbProvider::CloseFile(const ProtoBlob& options_blob) {
  int32_t error_code;
  CloseFileOptionsProto options;
  if (!ParseOptionsProto(options_blob, &options, &error_code)) {
    return error_code;
  }

  if (!IsMounted(options, &error_code)) {
    return error_code;
  }

  if (!CloseFile(options, options.file_id(), &error_code)) {
    return error_code;
  }

  return static_cast<int32_t>(ERROR_OK);
}

int32_t SmbProvider::DeleteEntry(const ProtoBlob& options_blob) {
  int32_t error_code;
  DeleteEntryOptionsProto options;
  std::string full_path;
  if (!ParseOptionsAndPath(options_blob, &options, &full_path, &error_code)) {
    return error_code;
  }

  bool is_directory;
  int32_t get_type_result;
  if (!GetEntryType(GetMountId(options), full_path, &get_type_result,
                    &is_directory)) {
    LogAndSetError(options, GetErrorFromErrno(get_type_result), &error_code);
    return error_code;
  }

  int32_t result;
  if (is_directory) {
    if (options.recursive()) {
      result = RecursiveDelete(GetMountId(options), full_path);
    } else {
      result = DeleteDirectory(GetMountId(options), full_path);
    }
  } else {
    result = DeleteFile(GetMountId(options), full_path);
  }

  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), &error_code);
    return error_code;
  }

  return static_cast<int32_t>(ERROR_OK);
}

void SmbProvider::ReadFile(const ProtoBlob& options_blob,
                           int32_t* error_code,
                           brillo::dbus_utils::FileDescriptor* temp_fd) {
  DCHECK(error_code);
  DCHECK(temp_fd);

  // TODO(allenvic): Investigate having a single shared buffer in the class.
  std::vector<uint8_t> buffer;
  ReadFileOptionsProto options;

  // The functions below will set the error if they fail.
  *error_code = static_cast<int32_t>(ERROR_OK);
  bool success = ParseOptionsProto(options_blob, &options, error_code) &&
                 IsMounted(options, error_code) && Seek(options, error_code) &&
                 ReadFileIntoBuffer(options, error_code, &buffer) &&
                 WriteTempFile(options, buffer, error_code, temp_fd);

  if (!success) {
    *temp_fd = GenerateEmptyFile();
  }
}

int32_t SmbProvider::CreateFile(const ProtoBlob& options_blob) {
  int32_t error_code;
  std::string full_path;
  CreateFileOptionsProto options;
  if (!ParseOptionsAndPath(options_blob, &options, &full_path, &error_code)) {
    return error_code;
  }

  int32_t file_id;
  // CreateFile() gives us back an open file descriptor to the newly created
  // file.
  if (!CreateFile(options, full_path, &file_id, &error_code)) {
    return error_code;
  }

  // Close the file handle from CreateFile().
  if (!CloseFile(options, file_id, &error_code)) {
    // Attempt to delete the file since file will not be usable.
    SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
    int32_t unlink_result = samba_interface->Unlink(full_path);
    if (unlink_result != 0) {
      // Log the unlink error but return the original error.
      LOG(ERROR) << "Error unlinking after error closing file: "
                 << GetErrorFromErrno(unlink_result);
    }
    return error_code;
  }

  return static_cast<int32_t>(ERROR_OK);
}

int32_t SmbProvider::Truncate(const ProtoBlob& options_blob) {
  int32_t error_code;
  std::string full_path;
  TruncateOptionsProto options;
  int32_t file_id;

  const bool result =
      ParseOptionsAndPath(options_blob, &options, &full_path, &error_code) &&
      OpenFile(options, full_path, &error_code, &file_id) &&
      TruncateAndCloseFile(options, file_id, options.length(), &error_code);

  return result ? static_cast<int32_t>(ERROR_OK) : error_code;
}

int32_t SmbProvider::WriteFile(const ProtoBlob& options_blob,
                               const base::ScopedFD& temp_fd) {
  int32_t error_code;
  WriteFileOptionsProto options;
  std::vector<uint8_t> buffer;

  const bool result =
      ParseOptionsProto(options_blob, &options, &error_code) &&
      ReadFromFD(options, temp_fd, &error_code, &buffer) &&
      Seek(options, &error_code) &&
      WriteFileFromBuffer(options, options.file_id(), buffer, &error_code);

  return result ? static_cast<int32_t>(ERROR_OK) : error_code;
}

int32_t SmbProvider::CreateDirectory(const ProtoBlob& options_blob) {
  int32_t error_code;
  CreateDirectoryOptionsProto options;
  std::string full_path;

  const bool result =
      ParseOptionsAndPath(options_blob, &options, &full_path, &error_code) &&
      CreateParentsIfNecessary(options, &error_code) &&
      CreateSingleDirectory(options, full_path, false /* ignore_existing */,
                            &error_code);

  return result ? static_cast<int32_t>(ERROR_OK) : error_code;
}

int32_t SmbProvider::MoveEntry(const ProtoBlob& options_blob) {
  int32_t error_code;
  std::string source_path;
  std::string target_path;
  MoveEntryOptionsProto options;

  const bool success =
      ParseOptionsAndPaths(options_blob, &options, &source_path, &target_path,
                           &error_code) &&
      MoveEntry(options, source_path, target_path, &error_code);

  return success ? static_cast<int32_t>(ERROR_OK) : error_code;
}

int32_t SmbProvider::CopyEntry(const ProtoBlob& options_blob) {
  int32_t error_code;
  std::string source_path;
  std::string target_path;
  CopyEntryOptionsProto options;

  const bool success =
      ParseOptionsAndPaths(options_blob, &options, &source_path, &target_path,
                           &error_code) &&
      CopyEntry(options, source_path, target_path, &error_code);

  return success ? static_cast<int32_t>(ERROR_OK) : error_code;
}

void SmbProvider::GetShares(const ProtoBlob& options_blob,
                            int32_t* error_code,
                            ProtoBlob* shares) {
  DCHECK(error_code);
  DCHECK(shares);

  ReadShareEntries(options_blob, error_code, shares);
}

void SmbProvider::SetupKerberos(SetupKerberosCallback callback,
                                const std::string& account_id) {
  kerberos_synchronizer_->SetupKerberos(
      account_id,
      base::Bind(&SmbProvider::HandleSetupKerberosResponse,
                 base::Unretained(this), base::Passed(std::move(callback))));
}

void SmbProvider::HandleSetupKerberosResponse(SetupKerberosCallback callback,
                                              bool result) {
  callback->Return(result);
}

ProtoBlob SmbProvider::ParseNetBiosPacket(const std::vector<uint8_t>& packet,
                                          uint16_t transaction_id) {
  const std::vector<std::string> servers =
      netbios::ParsePacket(packet, transaction_id);

  const HostnamesProto hostnames_proto = BuildHostnamesProto(servers);
  std::vector<uint8_t> out_blob;
  if (SerializeProtoToBlob(hostnames_proto, &out_blob) != ERROR_OK) {
    return ProtoBlob();
  }
  return out_blob;
}

void SmbProvider::StartCopy(const ProtoBlob& options_blob,
                            int32_t* error_code,
                            int32_t* copy_token) {
  DCHECK(error_code);
  DCHECK(copy_token);

  std::string source_path;
  std::string target_path;
  CopyEntryOptionsProto options;

  if (!ParseOptionsAndPaths(options_blob, &options, &source_path, &target_path,
                            error_code)) {
    return;
  }

  ErrorType error = StartCopy(options, source_path, target_path, copy_token);
  if (error != ERROR_OK || error != ERROR_COPY_PENDING) {
    LogAndSetError(options, error, error_code);
    return;
  }

  *error_code = static_cast<int32_t>(error);
}

int32_t SmbProvider::ContinueCopy(int32_t mount_id, int32_t copy_token) {
  DCHECK_GE(mount_id, 0);
  DCHECK_GE(copy_token, 0);

  int32_t error_code;
  if (!copy_tracker_.Contains(copy_token)) {
    LogAndSetError(kContinueCopyMethod, mount_id, ERROR_COPY_FAILED,
                   &error_code);
    return error_code;
  }

  if (!mount_manager_->IsAlreadyMounted(mount_id)) {
    copy_tracker_.Remove(copy_token);
    LogAndSetError(kContinueCopyMethod, mount_id, ERROR_COPY_FAILED,
                   &error_code);
    return error_code;
  }

  ErrorType error = ContinueCopy(copy_token);
  if (error != ERROR_OK && error != ERROR_COPY_PENDING) {
    LogAndSetError(kContinueCopyMethod, mount_id, error, &error_code);
    return error_code;
  }

  return static_cast<int32_t>(error);
}

HostnamesProto SmbProvider::BuildHostnamesProto(
    const std::vector<std::string>& hostnames) const {
  HostnamesProto hostnames_proto;
  for (const auto& hostname : hostnames) {
    AddToHostnamesProto(hostname, &hostnames_proto);
  }
  return hostnames_proto;
}

SambaInterface* SmbProvider::GetSambaInterface(int32_t mount_id) const {
  SambaInterface* samba_interface;
  if (mount_id == kInternalMountId) {
    samba_interface = mount_manager_->GetSystemSambaInterface();
  } else {
    bool success =
        mount_manager_->GetSambaInterface(mount_id, &samba_interface);
    DCHECK(success);
  }

  DCHECK(samba_interface);
  return samba_interface;
}

template <typename Proto>
bool SmbProvider::GetFullPath(const Proto* options,
                              std::string* full_path) const {
  DCHECK(options);
  DCHECK(full_path);

  const int32_t mount_id = GetMountId(*options);
  const std::string entry_path = GetEntryPath(*options);

  bool success = mount_manager_->GetFullPath(mount_id, entry_path, full_path);
  if (!success) {
    LOG(ERROR) << GetMethodName(*options) << " requested unknown mount_id "
               << mount_id;
  }

  return success;
}

template <>
bool SmbProvider::GetFullPath(const GetSharesOptionsProto* options,
                              std::string* full_path) const {
  DCHECK(options);
  DCHECK(full_path);

  *full_path = GetEntryPath(*options);
  return true;
}

template <typename Proto>
bool SmbProvider::GetFullPaths(const Proto* options,
                               std::string* source_full_path,
                               std::string* target_full_path) const {
  DCHECK(options);
  DCHECK(source_full_path);
  DCHECK(target_full_path);

  const int32_t mount_id = GetMountId(*options);
  const std::string source_path = GetSourcePath(*options);
  const std::string target_path = GetDestinationPath(*options);

  const bool success =
      mount_manager_->GetFullPath(mount_id, source_path, source_full_path) &&
      mount_manager_->GetFullPath(mount_id, target_path, target_full_path);
  if (!success) {
    LOG(ERROR) << GetMethodName(*options) << " requested unknown mount_id "
               << mount_id;
  }

  return success;
}

template <typename Proto>
bool SmbProvider::ParseOptionsAndPath(const ProtoBlob& blob,
                                      Proto* options,
                                      std::string* full_path,
                                      int32_t* error_code) {
  if (!ParseOptionsProto(blob, options, error_code)) {
    return false;
  }

  if (!GetFullPath(options, full_path)) {
    *error_code = static_cast<int32_t>(ERROR_NOT_FOUND);
    return false;
  }

  return true;
}

template <typename Proto>
bool SmbProvider::ParseOptionsAndPaths(const ProtoBlob& blob,
                                       Proto* options,
                                       std::string* source_path,
                                       std::string* target_path,
                                       int32_t* error_code) {
  DCHECK(options);
  DCHECK(source_path);
  DCHECK(target_path);
  DCHECK(error_code);

  if (!ParseOptionsProto(blob, options, error_code)) {
    return false;
  }

  if (!GetFullPaths(options, source_path, target_path)) {
    *error_code = static_cast<int32_t>(ERROR_NOT_FOUND);
    return false;
  }

  return true;
}

bool SmbProvider::GetEntryType(int32_t mount_id,
                               const std::string& full_path,
                               int32_t* error_code,
                               bool* is_directory) {
  DCHECK(error_code);
  DCHECK(is_directory);

  SambaInterface* samba_interface = GetSambaInterface(mount_id);
  struct stat stat_info;
  *error_code = samba_interface->GetEntryStatus(full_path.c_str(), &stat_info);
  if (*error_code != 0) {
    return false;
  }

  if (IsDirectory(stat_info)) {
    *is_directory = true;
    return true;
  }
  if (IsFile(stat_info)) {
    *is_directory = false;
    return true;
  }
  *error_code = ENOENT;
  return false;
}

template <typename Proto>
bool SmbProvider::Seek(const Proto& options, int32_t* error_code) {
  DCHECK(error_code);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->Seek(options.file_id(), options.offset());
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error_code);
    return false;
  }
  return true;
}

bool SmbProvider::CanAccessMount(int32_t mount_id,
                                 const std::string& mount_root,
                                 int32_t* error_code) {
  DCHECK(error_code);

  SambaInterface* samba_interface = GetSambaInterface(mount_id);
  int32_t dir_id = -1;
  int32_t result = samba_interface->OpenDirectory(mount_root, &dir_id);
  if (result != 0) {
    LogAndSetError(kMountMethod, -1, GetErrorFromErrno(result), error_code);
    return false;
  }

  CloseDirectory(mount_id, dir_id);
  return true;
}

void SmbProvider::CloseDirectory(int32_t mount_id, int32_t dir_id) {
  SambaInterface* samba_interface = GetSambaInterface(mount_id);
  int32_t result = samba_interface->CloseDirectory(dir_id);
  if (result != 0) {
    LOG(ERROR) << "Error closing directory " << dir_id;
  }
}

bool SmbProvider::RemoveMount(int32_t mount_id, int32_t* error_code) {
  bool removed = mount_manager_->RemoveMount(mount_id);
  if (!removed) {
    *error_code = static_cast<int32_t>(ERROR_NOT_FOUND);
  }

  return removed;
}

bool SmbProvider::AddMount(const std::string& mount_root,
                           const std::string& workgroup,
                           const std::string& username,
                           const base::ScopedFD& password_fd,
                           int32_t* error_code,
                           int32_t* mount_id) {
  SmbCredential credential(workgroup, username, GetPassword(password_fd));
  bool added =
      mount_manager_->AddMount(mount_root, std::move(credential), mount_id);
  if (!added) {
    *error_code = static_cast<int32_t>(ERROR_IN_USE);
  }

  return added;
}

bool SmbProvider::Remount(const std::string& mount_root,
                          int32_t mount_id,
                          const std::string& workgroup,
                          const std::string& username,
                          const base::ScopedFD& password_fd,
                          int32_t* error_code) {
  SmbCredential credential(workgroup, username, GetPassword(password_fd));
  bool remounted =
      mount_manager_->Remount(mount_root, mount_id, std::move(credential));
  if (!remounted) {
    *error_code = static_cast<int32_t>(ERROR_IN_USE);
  }

  return remounted;
}

void SmbProvider::RemoveMountIfMounted(int32_t mount_id) {
  if (mount_id != -1) {
    mount_manager_->RemoveMount(mount_id);
  }
}

bool SmbProvider::ReadFileIntoBuffer(const ReadFileOptionsProto& options,
                                     int32_t* error_code,
                                     std::vector<uint8_t>* buffer) {
  DCHECK(buffer);
  DCHECK(error_code);

  buffer->resize(options.length());
  size_t bytes_read;

  if (!ReadToBuffer(options, options.file_id(), buffer, &bytes_read,
                    error_code)) {
    return false;
  }
  return true;
}

template <typename Proto>
bool SmbProvider::WriteTempFile(const Proto& options,
                                const std::vector<uint8_t>& buffer,
                                int32_t* error_code,
                                brillo::dbus_utils::FileDescriptor* temp_fd) {
  base::ScopedFD scoped_fd = temp_file_manager_.CreateTempFile(buffer);
  if (!scoped_fd.is_valid()) {
    LogAndSetError(options, ERROR_IO, error_code);
    return false;
  }

  // get() is called here instead of release() since FileDescriptor duplicates
  // the FD when getting assigned, meaning the local FD still needs to be
  // closed by ScopedFD when it goes out of scope.
  *temp_fd = scoped_fd.get();
  return true;
}

template <typename Proto>
bool SmbProvider::WriteFileFromBuffer(const Proto& options,
                                      int32_t file_id,
                                      const std::vector<uint8_t>& buffer,
                                      int32_t* error_code) {
  DCHECK(error_code);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result =
      samba_interface->WriteFile(file_id, buffer.data(), buffer.size());
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error_code);
    return false;
  }
  return true;
}

int32_t SmbProvider::RecursiveDelete(int32_t mount_id,
                                     const std::string& dir_path) {
  PostDepthFirstIterator it = GetPostOrderIterator(mount_id, dir_path);
  int32_t it_result = it.Init();
  while (it_result == 0) {
    if (it.IsDone()) {
      return 0;
    }

    int32_t del_result = DeleteDirectoryEntry(mount_id, it.Get());
    if (del_result != 0) {
      return del_result;
    }

    it_result = it.Next();
  }

  // while-loop is only exited from if there's an iterator error.
  DCHECK_NE(0, it_result);
  return it_result;
}

int32_t SmbProvider::DeleteDirectoryEntry(int32_t mount_id,
                                          const DirectoryEntry& entry) {
  if (entry.is_directory) {
    return DeleteDirectory(mount_id, entry.full_path);
  }
  return DeleteFile(mount_id, entry.full_path);
}

int32_t SmbProvider::DeleteFile(int32_t mount_id,
                                const std::string& file_path) {
  SambaInterface* samba_interface = GetSambaInterface(mount_id);
  return samba_interface->Unlink(file_path.c_str());
}

int32_t SmbProvider::DeleteDirectory(int32_t mount_id,
                                     const std::string& dir_path) {
  SambaInterface* samba_interface = GetSambaInterface(mount_id);
  return samba_interface->RemoveDirectory(dir_path.c_str());
}

PostDepthFirstIterator SmbProvider::GetPostOrderIterator(
    int32_t mount_id, const std::string& full_path) {
  SambaInterface* samba_interface = GetSambaInterface(mount_id);
  return PostDepthFirstIterator(full_path, samba_interface);
}

template <typename Proto>
bool SmbProvider::OpenFile(const Proto& options,
                           const std::string& full_path,
                           int32_t* error,
                           int32_t* file_id) {
  DCHECK(error);
  DCHECK(file_id);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->OpenFile(
      full_path, GetOpenFilePermissions(options), file_id);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error);
    return false;
  }
  return true;
}

template <typename Proto>
bool SmbProvider::CloseFile(const Proto& options,
                            int32_t file_id,
                            int32_t* error) {
  DCHECK(error);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->CloseFile(file_id);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error);
    return false;
  }
  return true;
}

template <typename Proto>
bool SmbProvider::TruncateAndCloseFile(const Proto& options,
                                       const int32_t file_id,
                                       int64_t length,
                                       int32_t* error) {
  DCHECK(error);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t truncate_result = samba_interface->Truncate(file_id, length);
  if (truncate_result != 0) {
    LogAndSetError(options, GetErrorFromErrno(truncate_result), error);
    // Continue to close on error.
  }

  int32_t close_error;
  if (!CloseFile(options, file_id, &close_error)) {
    if (truncate_result == 0) {
      // If Truncate was successful, set error to the close error, otherwise
      // keep the truncate error.
      *error = close_error;
    }
    return false;
  }

  // Return if the truncate was successful.
  return truncate_result == 0;
}

bool SmbProvider::MoveEntry(const MoveEntryOptionsProto& options,
                            const std::string& source_path,
                            const std::string& target_path,
                            int32_t* error) {
  DCHECK(error);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->MoveEntry(source_path, target_path);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error);
    return false;
  }
  return true;
}

bool SmbProvider::GenerateParentPaths(
    const CreateDirectoryOptionsProto& options,
    int32_t* error_code,
    std::vector<std::string>* parent_paths) {
  DCHECK(error_code);
  DCHECK(parent_paths);
  base::FilePath current_path(options.directory_path());
  DCHECK(current_path.IsAbsolute());

  // Skip the leaf path and start with the lowest parent.
  current_path = current_path.DirName();

  while (current_path.value() != "/") {
    std::string full_path;
    if (!mount_manager_->GetFullPath(
            GetMountId(options), current_path.StripTrailingSeparators().value(),
            &full_path)) {
      *error_code = static_cast<int32_t>(ERROR_NOT_FOUND);
      return false;
    }

    current_path = current_path.DirName();
    parent_paths->push_back(std::move(full_path));
  }

  // Reverse the vector so the top parent will be first.
  std::reverse(parent_paths->begin(), parent_paths->end());
  return true;
}

bool SmbProvider::CreateNestedDirectories(
    const CreateDirectoryOptionsProto& options,
    const std::vector<std::string>& paths,
    int32_t* error_code) {
  DCHECK(error_code);

  for (auto const& path : paths) {
    if (!CreateSingleDirectory(options, path, true /* ignore_existing */,
                               error_code)) {
      return false;
    }
  }
  return true;
}

bool SmbProvider::CreateParentsIfNecessary(
    const CreateDirectoryOptionsProto& options, int32_t* error_code) {
  DCHECK(error_code);

  if (!options.recursive()) {
    // Return true in this case since no parents need to be created.
    return true;
  }

  std::vector<std::string> paths;
  return GenerateParentPaths(options, error_code, &paths) &&
         CreateNestedDirectories(options, paths, error_code);
}

template <typename Proto>
bool SmbProvider::CreateSingleDirectory(const Proto& options,
                                        const std::string& full_path,
                                        bool ignore_existing,
                                        int32_t* error_code) {
  DCHECK(error_code);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  const int32_t result = samba_interface->CreateDirectory(full_path);
  if (ShouldReportCreateDirError(result, ignore_existing)) {
    LogAndSetError(options, GetErrorFromErrno(result), error_code);
    return false;
  }

  return true;
}

template <typename Proto>
bool SmbProvider::CreateFile(const Proto& options,
                             const std::string& full_path,
                             int32_t* file_id,
                             int32_t* error) {
  DCHECK(file_id);
  DCHECK(error);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->CreateFile(full_path, file_id);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error);
    return false;
  }
  return true;
}

bool SmbProvider::CopyEntry(const CopyEntryOptionsProto& options,
                            const std::string& source_path,
                            const std::string& target_path,
                            int32_t* error_code) {
  DCHECK(error_code);
  bool is_directory;
  int32_t get_type_result;
  if (!GetEntryType(GetMountId(options), source_path, &get_type_result,
                    &is_directory)) {
    LogAndSetError(options, GetErrorFromErrno(get_type_result), error_code);
    return false;
  }

  if (is_directory) {
    return CreateSingleDirectory(options, target_path,
                                 false /* ignore_existing */, error_code);
  }

  return CopyFile(options, source_path, target_path, error_code);
}

bool SmbProvider::CopyFile(const CopyEntryOptionsProto& options,
                           const std::string& source_path,
                           const std::string& target_path,
                           int32_t* error_code) {
  DCHECK(error_code);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->CopyFile(source_path, target_path);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error_code);
    return false;
  }

  return true;
}

ErrorType SmbProvider::StartCopy(const CopyEntryOptionsProto& options,
                                 const std::string& source_path,
                                 const std::string& target_path,
                                 int32_t* copy_token) {
  DCHECK(copy_token);

  bool is_directory;
  int32_t get_type_result;
  if (!GetEntryType(GetMountId(options), source_path, &get_type_result,
                    &is_directory)) {
    return GetErrorFromErrno(get_type_result);
  }

  if (is_directory) {
    return StartDirectoryCopy(options, source_path, target_path, copy_token);
  }

  return StartFileCopy(options, source_path, target_path, copy_token);
}

template <typename CopyProgressType>
ErrorType SmbProvider::StartCopyProgress(const CopyEntryOptionsProto& options,
                                         const std::string& source_path,
                                         const std::string& target_path,
                                         int32_t* copy_token) {
  DCHECK(copy_token);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  auto copy_progress = std::make_unique<CopyProgressType>(samba_interface);

  int32_t copy_result;
  bool should_continue_copy =
      copy_progress->StartCopy(source_path, target_path, &copy_result);
  if (should_continue_copy) {
    // The copy needs to be continued.
    *copy_token = copy_tracker_.Insert(std::move(copy_progress));
    return ERROR_COPY_PENDING;
  }
  if (copy_result == 0) {
    // The copy is complete.
    return ERROR_OK;
  }

  return GetErrorFromErrno(copy_result);
}

ErrorType SmbProvider::StartDirectoryCopy(const CopyEntryOptionsProto& options,
                                          const std::string& source_path,
                                          const std::string& target_path,
                                          int32_t* copy_token) {
  DCHECK(copy_token);

  return StartCopyProgress<RecursiveCopyProgress>(options, source_path,
                                                  target_path, copy_token);
}

ErrorType SmbProvider::StartFileCopy(const CopyEntryOptionsProto& options,
                                     const std::string& source_path,
                                     const std::string& target_path,
                                     int32_t* copy_token) {
  DCHECK(copy_token);

  return StartCopyProgress<FileCopyProgress>(options, source_path, target_path,
                                             copy_token);
}

ErrorType SmbProvider::ContinueCopy(int32_t copy_token) {
  DCHECK_GE(copy_token, 0);
  DCHECK(copy_tracker_.Contains(copy_token));

  int32_t copy_result;
  const bool should_continue_copy =
      copy_tracker_.Find(copy_token)->second->ContinueCopy(&copy_result);
  if (should_continue_copy) {
    // The copy needs to be continued.
    return ERROR_COPY_PENDING;
  }

  // The copy no longer needs to be continued as it has either completed
  // successfully or it failed so remove it from |copy_tracker_|.
  copy_tracker_.Remove(copy_token);

  if (copy_result == 0) {
    // The copy is complete.
    return ERROR_OK;
  }

  return GetErrorFromErrno(copy_result);
}

template <typename Proto>
bool SmbProvider::ReadToBuffer(const Proto& options,
                               int32_t file_id,
                               std::vector<uint8_t>* buffer,
                               size_t* bytes_read,
                               int32_t* error_code) {
  DCHECK(buffer);
  DCHECK(bytes_read);
  DCHECK(error_code);

  SambaInterface* samba_interface = GetSambaInterface(GetMountId(options));
  int32_t result = samba_interface->ReadFile(file_id, buffer->data(),
                                             buffer->size(), bytes_read);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error_code);
    return false;
  }

  DCHECK_GE(*bytes_read, 0);
  DCHECK_LE(*bytes_read, buffer->size());
  // Make sure buffer is only as big as bytes_read.
  buffer->resize(*bytes_read);
  return true;
}

void SmbProvider::GetDeleteList(const ProtoBlob& options_blob,
                                int32_t* error_code,
                                brillo::dbus_utils::FileDescriptor* temp_fd,
                                int32_t* bytes_written) {
  DCHECK(error_code);
  DCHECK(temp_fd);
  DCHECK(bytes_written);

  std::string full_path;
  GetDeleteListOptionsProto options;
  if (!ParseOptionsAndPath(options_blob, &options, &full_path, error_code)) {
    *temp_fd = GenerateEmptyFile();
    return;
  }

  bool is_directory;
  int32_t get_type_result;
  if (!GetEntryType(GetMountId(options), full_path, &get_type_result,
                    &is_directory)) {
    LogAndSetError(options, GetErrorFromErrno(get_type_result), error_code);
    *temp_fd = GenerateEmptyFile();
    return;
  }

  DeleteListProto delete_list;
  int32_t result =
      GenerateDeleteList(options, full_path, is_directory, &delete_list);
  if (result != 0) {
    LogAndSetError(options, GetErrorFromErrno(result), error_code);
    *temp_fd = GenerateEmptyFile();
    return;
  }

  WriteDeleteListToTempFile(options, delete_list, error_code, temp_fd,
                            bytes_written);
}

bool SmbProvider::WriteDeleteListToTempFile(
    const GetDeleteListOptionsProto& options,
    const DeleteListProto& delete_list,
    int32_t* error_code,
    brillo::dbus_utils::FileDescriptor* temp_fd,
    int32_t* bytes_written) {
  DCHECK(error_code);
  DCHECK(temp_fd);
  DCHECK(bytes_written);

  std::vector<uint8_t> buffer;
  *error_code =
      static_cast<int32_t>(SerializeProtoToBlob(delete_list, &buffer));
  if (*error_code != ERROR_OK) {
    *temp_fd = GenerateEmptyFile();
    return false;
  }

  bool success = WriteTempFile(options, buffer, error_code, temp_fd);
  *bytes_written = success ? buffer.size() : -1;

  return success;
}

int32_t SmbProvider::GenerateDeleteList(
    const GetDeleteListOptionsProto& options,
    const std::string& full_path,
    bool is_directory,
    DeleteListProto* delete_list) {
  DCHECK(delete_list);

  if (!is_directory) {
    // |delete_list| will only contain the relative path to the file.
    AddToDeleteList(GetRelativePath(GetMountId(options), full_path),
                    delete_list);
    return 0;
  }

  PostDepthFirstIterator it =
      GetPostOrderIterator(GetMountId(options), full_path);
  int32_t it_result = it.Init();
  while (it_result == 0) {
    if (it.IsDone()) {
      return 0;
    }

    AddToDeleteList(GetRelativePath(GetMountId(options), it.Get().full_path),
                    delete_list);
    it_result = it.Next();
  }

  // while-loop is only exited from if there's an iterator error.
  DCHECK_NE(0, it_result);
  return it_result;
}

bool SmbProvider::GetCachedEntry(int32_t mount_id,
                                 const std::string full_path,
                                 ProtoBlob* out_entry) {
  MetadataCache* cache = nullptr;
  if (!mount_manager_->GetMetadataCache(mount_id, &cache)) {
    return false;
  }

  DCHECK(cache);
  DirectoryEntry entry;
  if (!cache->FindEntry(full_path, &entry)) {
    return false;
  }

  DirectoryEntryProto proto;
  ConvertToProto(entry, &proto);
  if (SerializeProtoToBlob(proto, out_entry) != ERROR_OK) {
    return false;
  }

  return true;
}

brillo::dbus_utils::FileDescriptor SmbProvider::GenerateEmptyFile() {
  base::ScopedFD temp_fd = temp_file_manager_.CreateTempFile();
  DCHECK(temp_fd.is_valid());

  // get() is called here instead of release() since FileDescriptor duplicates
  // the FD when getting assigned, meaning the local FD still needs to be
  // closed by ScopedFD when it goes out of scope.
  return brillo::dbus_utils::FileDescriptor(temp_fd.get());
}

std::string SmbProvider::GetRelativePath(int32_t mount_id,
                                         const std::string& entry_path) {
  return mount_manager_->GetRelativePath(mount_id, entry_path);
}

template <typename Proto>
bool SmbProvider::IsMounted(const Proto& options, int32_t* error_code) const {
  const bool is_valid = mount_manager_->IsAlreadyMounted(GetMountId(options));
  if (!is_valid) {
    LogAndSetError(options, ERROR_NOT_FOUND, error_code);
  }
  return is_valid;
}

// These are required to explicitly instantiate the template functions.
template ErrorType SmbProvider::StartCopyProgress<FileCopyProgress>(
    const CopyEntryOptionsProto&,
    const std::string&,
    const std::string&,
    int32_t*);
template ErrorType SmbProvider::StartCopyProgress<RecursiveCopyProgress>(
    const CopyEntryOptionsProto&,
    const std::string&,
    const std::string&,
    int32_t*);

}  // namespace smbprovider
