// Copyright 2014 The Chromium 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 "components/storage_monitor/storage_monitor.h"

#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/storage_monitor/removable_storage_observer.h"
#include "components/storage_monitor/transient_device_ids.h"

namespace storage_monitor {

namespace {

StorageMonitor* g_storage_monitor = NULL;

}  // namespace

StorageMonitor::Receiver::~Receiver() {
}

class StorageMonitor::ReceiverImpl : public StorageMonitor::Receiver {
 public:
  explicit ReceiverImpl(StorageMonitor* notifications)
      : notifications_(notifications) {}

  virtual ~ReceiverImpl() {}

  virtual void ProcessAttach(const StorageInfo& info) OVERRIDE;

  virtual void ProcessDetach(const std::string& id) OVERRIDE;

  virtual void MarkInitialized() OVERRIDE;

 private:
  StorageMonitor* notifications_;
};

void StorageMonitor::ReceiverImpl::ProcessAttach(const StorageInfo& info) {
  notifications_->ProcessAttach(info);
}

void StorageMonitor::ReceiverImpl::ProcessDetach(const std::string& id) {
  notifications_->ProcessDetach(id);
}

void StorageMonitor::ReceiverImpl::MarkInitialized() {
  notifications_->MarkInitialized();
}

// static
void StorageMonitor::Create() {
  delete g_storage_monitor;
  g_storage_monitor = CreateInternal();
}

// static
void StorageMonitor::Destroy() {
  delete g_storage_monitor;
  g_storage_monitor = NULL;
}

StorageMonitor* StorageMonitor::GetInstance() {
  return g_storage_monitor;
}

void StorageMonitor::SetStorageMonitorForTesting(
    scoped_ptr<StorageMonitor> storage_monitor) {
  delete g_storage_monitor;
  g_storage_monitor = storage_monitor.release();
}

std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
  std::vector<StorageInfo> results;

  base::AutoLock lock(storage_lock_);
  for (StorageMap::const_iterator it = storage_map_.begin();
       it != storage_map_.end();
       ++it) {
    results.push_back(it->second);
  }
  return results;
}

void StorageMonitor::EnsureInitialized(base::Closure callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (initialized_) {
    if (!callback.is_null())
      callback.Run();
    return;
  }

  if (!callback.is_null()) {
    on_initialize_callbacks_.push_back(callback);
  }

  if (initializing_)
    return;

  initializing_ = true;
  Init();
}

bool StorageMonitor::IsInitialized() const {
  return initialized_;
}

void StorageMonitor::AddObserver(RemovableStorageObserver* obs) {
  observer_list_->AddObserver(obs);
}

void StorageMonitor::RemoveObserver(
    RemovableStorageObserver* obs) {
  observer_list_->RemoveObserver(obs);
}

std::string StorageMonitor::GetTransientIdForDeviceId(
    const std::string& device_id) {
  return transient_device_ids_->GetTransientIdForDeviceId(device_id);
}

std::string StorageMonitor::GetDeviceIdForTransientId(
    const std::string& transient_id) const {
  return transient_device_ids_->DeviceIdFromTransientId(transient_id);
}

void StorageMonitor::EjectDevice(
    const std::string& device_id,
    base::Callback<void(EjectStatus)> callback) {
  // Platform-specific implementations will override this method to
  // perform actual device ejection.
  callback.Run(EJECT_FAILURE);
}

StorageMonitor::StorageMonitor()
    : observer_list_(new ObserverListThreadSafe<RemovableStorageObserver>()),
      initializing_(false),
      initialized_(false),
      transient_device_ids_(new TransientDeviceIds) {
  receiver_.reset(new ReceiverImpl(this));
}

StorageMonitor::~StorageMonitor() {
}

StorageMonitor::Receiver* StorageMonitor::receiver() const {
  return receiver_.get();
}

void StorageMonitor::MarkInitialized() {
  initialized_ = true;
  for (std::vector<base::Closure>::iterator iter =
           on_initialize_callbacks_.begin();
       iter != on_initialize_callbacks_.end(); ++iter) {
    iter->Run();
  }
  on_initialize_callbacks_.clear();
}

void StorageMonitor::ProcessAttach(const StorageInfo& info) {
  {
    base::AutoLock lock(storage_lock_);
    if (ContainsKey(storage_map_, info.device_id())) {
      // This can happen if our unique id scheme fails. Ignore the incoming
      // non-unique attachment.
      return;
    }
    storage_map_.insert(std::make_pair(info.device_id(), info));
  }

  DVLOG(1) << "StorageAttached id " << info.device_id();
  if (StorageInfo::IsRemovableDevice(info.device_id())) {
    observer_list_->Notify(
        &RemovableStorageObserver::OnRemovableStorageAttached, info);
  }
}

void StorageMonitor::ProcessDetach(const std::string& id) {
  StorageInfo info;
  {
    base::AutoLock lock(storage_lock_);
    StorageMap::iterator it = storage_map_.find(id);
    if (it == storage_map_.end())
      return;
    info = it->second;
    storage_map_.erase(it);
  }

  DVLOG(1) << "StorageDetached for id " << id;
  if (StorageInfo::IsRemovableDevice(info.device_id())) {
    observer_list_->Notify(
        &RemovableStorageObserver::OnRemovableStorageDetached, info);
  }
}

}  // namespace storage_monitor
