// 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 <map>
#include <utility>

#include <base/files/file_path.h>
#include <base/memory/ptr_util.h>
#include <errno.h>

#include "smbprovider/constants.h"
#include "smbprovider/proto_bindings/directory_entry.pb.h"
#include "smbprovider/samba_interface_impl.h"
#include "smbprovider/smbprovider.h"
#include "smbprovider/smbprovider_helper.h"

using brillo::dbus_utils::DBusObject;

namespace smbprovider {

namespace {

// Maps errno to ErrorType.
ErrorType GetErrorFromErrno(int32_t err) {
  ErrorType error;
  switch (err) {
    case EPERM:
    case EACCES:
      error = ERROR_ACCESS_DENIED;
      break;
    case EBADF:
    case ENODEV:
    case ENOENT:
      error = ERROR_NOT_FOUND;
      break;
    case EMFILE:
    case ENFILE:
      error = ERROR_TOO_MANY_OPENED;
      break;
    default:
      error = ERROR_FAILED;
      break;
  }
  return error;
}

// Logs error and sets |error_code|.
void LogAndSetError(const std::string& operation_name,
                    int32_t mount_id,
                    ErrorType error_received,
                    int32_t* error_code) {
  LOG(ERROR) << "Error performing " << operation_name
             << " from mount id: " << mount_id << ": " << error_received;
  *error_code = static_cast<int32_t>(error_received);
}

// Serializes |proto| to the byte array |proto_blob|. Return ERROR_OK on success
// and ERROR_INVALID_OPERATION otherwise.
template <typename ProtoType>
int32_t SerializeProto(const ProtoType& proto,
                       std::vector<uint8_t>* proto_blob) {
  DCHECK(proto_blob);
  std::string buffer;
  if (!proto.SerializeToString(&buffer)) {
    LOG(ERROR) << "Failed to serialize proto";
    return static_cast<int32_t>(ERROR_INVALID_OPERATION);
  }
  proto_blob->assign(buffer.begin(), buffer.end());
  return static_cast<int32_t>(ERROR_OK);
}

// Helper method to get |DirectoryEntry| from a struct stat. Returns ERROR_OK
// on success and ERROR_INVALID_OPERATION otherwise.
int32_t GetDirectoryEntryFromStat(const std::string& full_path,
                                  const struct stat& stat_info,
                                  std::vector<uint8_t>* proto_blob) {
  DCHECK(proto_blob);
  bool is_directory = S_ISDIR(stat_info.st_mode);
  int64_t size = is_directory ? 0 : stat_info.st_size;
  const base::FilePath path(full_path);

  DirectoryEntry entry;
  entry.set_is_directory(is_directory);
  entry.set_name(path.BaseName().value());
  entry.set_size(size);
  entry.set_last_modified_time(stat_info.st_mtime);

  return SerializeProto(entry, proto_blob);
}

}  // namespace

SmbProvider::SmbProvider(
    std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object,
    std::unique_ptr<smbprovider::SambaInterface> samba_interface,
    size_t buffer_size)
    : org::chromium::SmbProviderAdaptor(this),
      samba_interface_(std::move(samba_interface)),
      dbus_object_(std::move(dbus_object)),
      dir_buf_(buffer_size) {}

SmbProvider::SmbProvider(
    std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object,
    std::unique_ptr<smbprovider::SambaInterface> samba_interface)
    : SmbProvider(
          std::move(dbus_object), std::move(samba_interface), kBufferSize) {}

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

void SmbProvider::Mount(const std::string& share_path,
                        int32_t* error_code,
                        int32_t* mount_id) {
  DCHECK(error_code);
  DCHECK(mount_id);
  int32_t dir_id = -1;
  int32_t open_dir_error = samba_interface_->OpenDirectory(share_path, &dir_id);
  if (open_dir_error != 0) {
    *mount_id = -1;
    LogAndSetError("Mount", -1, GetErrorFromErrno(open_dir_error), error_code);
    return;
  }
  current_mount_id_++;
  DCHECK(mounts_.find(current_mount_id_) == mounts_.end());
  mounts_[current_mount_id_] = share_path;
  CloseDirectory(dir_id);
  *mount_id = current_mount_id_;
  *error_code = static_cast<int32_t>(ERROR_OK);
}

int32_t SmbProvider::Unmount(int32_t mount_id) {
  ErrorType err = mounts_.erase(mount_id) == 0 ? ERROR_NOT_FOUND : ERROR_OK;
  return static_cast<int32_t>(err);
}

void SmbProvider::ReadDirectory(int32_t mount_id,
                                const std::string& directory_path,
                                int32_t* error_code,
                                std::vector<uint8_t>* out_entries) {
  DCHECK(error_code);
  DCHECK(out_entries);
  out_entries->clear();
  std::string share_path;
  if (!GetMountPathFromId(mount_id, &share_path)) {
    LogAndSetError("ReadDirectory", mount_id, ERROR_NOT_FOUND, error_code);
    return;
  }
  // |full_directory_path| is smb://server/share/directory.
  std::string full_directory_path = AppendPath(share_path, directory_path);
  int32_t dir_id = -1;
  int32_t open_dir_error =
      samba_interface_->OpenDirectory(full_directory_path, &dir_id);
  if (open_dir_error != 0) {
    LogAndSetError("ReadDirectory", mount_id, GetErrorFromErrno(open_dir_error),
                   error_code);
    return;
  }
  DirectoryEntryList directory_entries;
  int32_t get_dir_error = GetDirectoryEntries(dir_id, &directory_entries);
  if (get_dir_error != 0) {
    LogAndSetError("ReadDirectory", mount_id, GetErrorFromErrno(get_dir_error),
                   error_code);
    CloseDirectory(dir_id);
    return;
  }
  *error_code = SerializeProto(directory_entries, out_entries);
  CloseDirectory(dir_id);
}

void SmbProvider::GetMetadataEntry(int32_t mount_id,
                                   const std::string& entry_path,
                                   int32_t* error_code,
                                   std::vector<uint8_t>* out_entry) {
  DCHECK(error_code);
  DCHECK(out_entry);
  out_entry->clear();
  std::string share_path;
  if (!GetMountPathFromId(mount_id, &share_path)) {
    LogAndSetError("GetMetadataEntry", mount_id, ERROR_NOT_FOUND, error_code);
    return;
  }
  const std::string full_path = AppendPath(share_path, entry_path);
  struct stat stat_info;
  int32_t get_status_error =
      samba_interface_->GetEntryStatus(full_path.c_str(), &stat_info);
  if (get_status_error != 0) {
    LogAndSetError("GetMetadataEntry", mount_id,
                   GetErrorFromErrno(get_status_error), error_code);
    return;
  }
  *error_code = GetDirectoryEntryFromStat(full_path, stat_info, out_entry);
}

// This is a helper method that has a similar return structure as
// samba_interface_ methods, where it will return errno as an error in case of
// failure.
int32_t SmbProvider::GetDirectoryEntries(int32_t dir_id,
                                         DirectoryEntryList* entries) {
  DCHECK(entries);
  int32_t bytes_read = 0;
  do {
    int32_t result = samba_interface_->GetDirectoryEntries(
        dir_id, GetDirentFromBuffer(dir_buf_.data()), dir_buf_.size(),
        &bytes_read);
    if (result != 0) {
      // The result will be set to errno on failure.
      return result;
    }
    int32_t bytes_left = bytes_read;
    smbc_dirent* dirent = GetDirentFromBuffer(dir_buf_.data());
    while (bytes_left > 0) {
      AddEntryIfValid(*dirent, entries);
      DCHECK_GT(dirent->dirlen, 0);
      DCHECK_GE(bytes_left, dirent->dirlen);
      bytes_left -= dirent->dirlen;
      dirent = AdvanceDirEnt(dirent);
      DCHECK(dirent);
    }
    DCHECK_EQ(bytes_left, 0);
  } while (bytes_read > 0);
  return 0;
}

bool SmbProvider::GetMountPathFromId(int32_t mount_id,
                                     std::string* share_path) const {
  DCHECK(share_path);
  auto mount_iter = mounts_.find(mount_id);
  if (mount_iter == mounts_.end()) {
    return false;
  }
  *share_path = mount_iter->second;
  return true;
}

void SmbProvider::CloseDirectory(int32_t dir_id) {
  int32_t result = samba_interface_->CloseDirectory(dir_id);
  if (result != 0) {
    LOG(ERROR) << "Error closing directory " << dir_id;
  }
}

}  // namespace smbprovider
