// Copyright (c) 2012 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 "mtpd/mtpd_server_impl.h"

#include <base/containers/contains.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <chromeos/dbus/service_constants.h>

namespace mtpd {

namespace {

// Maximum number of bytes to read from the device at one time. This is set low
// enough such that a reasonable device can read this much data before D-Bus
// times out.
const uint32_t kMaxReadCount = 1024 * 1024;

void AddError(brillo::ErrorPtr* error,
              const base::Location& location,
              const std::string& message) {
  brillo::Error::AddTo(error, location, brillo::errors::dbus::kDomain,
                       kMtpdServiceError, message);
}

void AddInvalidHandleError(brillo::ErrorPtr* error,
                           const base::Location& location,
                           const std::string& handle) {
  brillo::Error::AddToPrintf(error, location, brillo::errors::dbus::kDomain,
                             kMtpdServiceError, "Invalid handle %s",
                             handle.c_str());
}

}  // namespace

MtpdServer::MtpdServer(scoped_refptr<dbus::Bus> bus)
    : org::chromium::MtpdAdaptor(this),
      dbus_object_(nullptr, bus, dbus::ObjectPath(kMtpdServicePath)),
      device_manager_(this) {}

MtpdServer::~MtpdServer() {}

std::vector<std::string> MtpdServer::EnumerateStorages() {
  return device_manager_.EnumerateStorages();
}

std::vector<uint8_t> MtpdServer::GetStorageInfo(
    const std::string& storage_name) {
  const StorageInfo* info = device_manager_.GetStorageInfo(storage_name);
  return info ? info->ToDBusFormat() : StorageInfo().ToDBusFormat();
}

std::vector<uint8_t> MtpdServer::GetStorageInfoFromDevice(
    const std::string& storage_name) {
  const StorageInfo* info =
      device_manager_.GetStorageInfoFromDevice(storage_name);
  return info ? info->ToDBusFormat() : StorageInfo().ToDBusFormat();
}

bool MtpdServer::OpenStorage(brillo::ErrorPtr* error,
                             const std::string& storage_name,
                             const std::string& mode,
                             std::string* id) {
  if (!(mode == kReadOnlyMode || mode == kReadWriteMode)) {
    brillo::Error::AddToPrintf(error, FROM_HERE, brillo::errors::dbus::kDomain,
                               kMtpdServiceError, "Cannot open %s in mode: %s",
                               storage_name.c_str(), mode.c_str());
    return false;
  }

  if (!device_manager_.HasStorage(storage_name)) {
    brillo::Error::AddToPrintf(
        error, FROM_HERE, brillo::errors::dbus::kDomain, kMtpdServiceError,
        "Cannot open unknown storage %s", storage_name.c_str());
    return false;
  }

  std::string new_id;
  uint32_t random_data[4];
  do {
    base::RandBytes(random_data, sizeof(random_data));
    new_id = base::HexEncode(random_data, sizeof(random_data));
  } while (base::Contains(handle_map_, new_id));

  handle_map_.insert(
      std::make_pair(new_id, std::make_pair(storage_name, mode)));
  *id = new_id;
  return true;
}

bool MtpdServer::CloseStorage(brillo::ErrorPtr* error,
                              const std::string& handle) {
  if (handle_map_.erase(handle) == 0) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  return true;
}

bool MtpdServer::ReadDirectoryEntryIds(
    brillo::ErrorPtr* error,
    const std::string& handle,
    uint32_t file_id,
    std::vector<uint32_t>* directory_listing) {
  std::string storage_name = LookupHandle(handle);
  if (storage_name.empty()) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  if (!device_manager_.ReadDirectoryEntryIds(storage_name, file_id,
                                             directory_listing)) {
    AddError(error, FROM_HERE, "ReadDirectoryEntryIds failed");
    return false;
  }

  return true;
}

bool MtpdServer::GetFileInfo(brillo::ErrorPtr* error,
                             const std::string& handle,
                             const std::vector<uint32_t>& file_ids,
                             std::vector<uint8_t>* serialized_file_entries) {
  if (file_ids.empty()) {
    AddError(error, FROM_HERE, "GetFileInfo called with no file ids");
    return false;
  }

  std::string storage_name = LookupHandle(handle);
  if (storage_name.empty()) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  std::vector<FileEntry> file_info;
  if (!device_manager_.GetFileInfo(storage_name, file_ids, &file_info)) {
    AddError(error, FROM_HERE, "GetFileInfo failed");
    return false;
  }

  *serialized_file_entries = FileEntry::FileEntriesToDBusFormat(file_info);
  return true;
}

bool MtpdServer::ReadFileChunk(brillo::ErrorPtr* error,
                               const std::string& handle,
                               uint32_t file_id,
                               uint32_t offset,
                               uint32_t count,
                               std::vector<uint8_t>* file_contents) {
  if (count > kMaxReadCount || count == 0) {
    AddError(error, FROM_HERE, "Invalid count for ReadFileChunk");
    return false;
  }
  std::string storage_name = LookupHandle(handle);
  if (storage_name.empty()) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  if (!device_manager_.ReadFileChunk(storage_name, file_id, offset, count,
                                     file_contents)) {
    AddError(error, FROM_HERE, "ReadFileChunk failed");
    return false;
  }

  return true;
}

bool MtpdServer::CopyFileFromLocal(brillo::ErrorPtr* error,
                                   const std::string& handle,
                                   const base::ScopedFD& file_descriptor,
                                   uint32_t parent_id,
                                   const std::string& file_name) {
  const std::string storage_name = LookupHandle(handle);
  if (storage_name.empty() || !IsOpenedWithWrite(handle)) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  if (!device_manager_.CopyFileFromLocal(storage_name, file_descriptor.get(),
                                         parent_id, file_name)) {
    AddError(error, FROM_HERE, "CopyFileFromLocal failed");
    return false;
  }

  return true;
}

bool MtpdServer::DeleteObject(brillo::ErrorPtr* error,
                              const std::string& handle,
                              uint32_t object_id) {
  const std::string storage_name = LookupHandle(handle);
  if (storage_name.empty() || !IsOpenedWithWrite(handle)) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  if (!device_manager_.DeleteObject(storage_name, object_id)) {
    AddError(error, FROM_HERE, "DeleteObject failed");
    return false;
  }

  return true;
}

bool MtpdServer::RenameObject(brillo::ErrorPtr* error,
                              const std::string& handle,
                              uint32_t object_id,
                              const std::string& new_name) {
  const std::string storage_name = LookupHandle(handle);
  if (storage_name.empty() || !IsOpenedWithWrite(handle)) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  if (!device_manager_.RenameObject(storage_name, object_id, new_name)) {
    AddError(error, FROM_HERE, "RenameObject failed");
    return false;
  }

  return true;
}

bool MtpdServer::CreateDirectory(brillo::ErrorPtr* error,
                                 const std::string& handle,
                                 uint32_t parent_id,
                                 const std::string& directory_name) {
  const std::string storage_name = LookupHandle(handle);
  if (storage_name.empty() || !IsOpenedWithWrite(handle)) {
    AddInvalidHandleError(error, FROM_HERE, handle);
    return false;
  }

  if (!device_manager_.CreateDirectory(storage_name, parent_id,
                                       directory_name)) {
    AddError(error, FROM_HERE, "CreateDirectory failed.");
    return false;
  }

  return true;
}

bool MtpdServer::IsAlive() {
  return true;
}

void MtpdServer::StorageAttached(const std::string& storage_name) {
  // Fire DBus signal.
  SendMTPStorageAttachedSignal(storage_name);
}

void MtpdServer::StorageDetached(const std::string& storage_name) {
  // Fire DBus signal.
  SendMTPStorageDetachedSignal(storage_name);
}

int MtpdServer::GetDeviceEventDescriptor() const {
  return device_manager_.GetDeviceEventDescriptor();
}

void MtpdServer::ProcessDeviceEvents() {
  device_manager_.ProcessDeviceEvents();
}

std::string MtpdServer::LookupHandle(const std::string& handle) {
  HandleMap::const_iterator it = handle_map_.find(handle);
  return (it == handle_map_.end()) ? std::string() : it->second.first;
}

bool MtpdServer::IsOpenedWithWrite(const std::string& handle) {
  HandleMap::const_iterator it = handle_map_.find(handle);
  return (it == handle_map_.end()) ? false
                                   : it->second.second == kReadWriteMode;
}

void MtpdServer::RegisterAsync(
    const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb) {
  RegisterWithDBusObject(&dbus_object_);
  dbus_object_.RegisterAsync(cb);
}

}  // namespace mtpd
