// Copyright (c) 2012 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 "chrome/browser/browsing_data/browsing_data_file_system_helper.h"

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_quota_util.h"
#include "webkit/common/fileapi/file_system_types.h"

using content::BrowserThread;

namespace fileapi {
class FileSystemContext;
}

namespace {

// An implementation of the BrowsingDataFileSystemHelper interface that pulls
// data from a given |filesystem_context| and returns a list of FileSystemInfo
// items to a client.
class BrowsingDataFileSystemHelperImpl : public BrowsingDataFileSystemHelper {
 public:
  // BrowsingDataFileSystemHelper implementation
  explicit BrowsingDataFileSystemHelperImpl(
      fileapi::FileSystemContext* filesystem_context);
  virtual void StartFetching(const base::Callback<
      void(const std::list<FileSystemInfo>&)>& callback) OVERRIDE;
  virtual void DeleteFileSystemOrigin(const GURL& origin) OVERRIDE;

 private:
  virtual ~BrowsingDataFileSystemHelperImpl();

  // Enumerates all filesystem files, storing the resulting list into
  // file_system_file_ for later use. This must be called on the file
  // task runner.
  void FetchFileSystemInfoInFileThread();

  // Triggers the success callback as the end of a StartFetching workflow. This
  // must be called on the UI thread.
  void NotifyOnUIThread();

  // Deletes all file systems associated with |origin|. This must be called on
  // the file task runner.
  void DeleteFileSystemOriginInFileThread(const GURL& origin);

  // Returns the file task runner for the |filesystem_context_|.
  base::SequencedTaskRunner* file_task_runner() {
    return filesystem_context_->default_file_task_runner();
  }

  // Keep a reference to the FileSystemContext object for the current profile
  // for use on the file task runner.
  scoped_refptr<fileapi::FileSystemContext> filesystem_context_;

  // Holds the current list of file systems returned to the client after
  // StartFetching is called. Access to |file_system_info_| is triggered
  // indirectly via the UI thread and guarded by |is_fetching_|. This means
  // |file_system_info_| is only accessed while |is_fetching_| is true. The
  // flag |is_fetching_| is only accessed on the UI thread. In the context of
  // this class |file_system_info_| only mutates on the file task runner.
  std::list<FileSystemInfo> file_system_info_;

  // Holds the callback passed in at the beginning of the StartFetching workflow
  // so that it can be triggered via NotifyOnUIThread. This only mutates on the
  // UI thread.
  base::Callback<void(const std::list<FileSystemInfo>&)> completion_callback_;

  // Indicates whether or not we're currently fetching information: set to true
  // when StartFetching is called on the UI thread, and reset to false when
  // NotifyOnUIThread triggers the success callback.
  // This property only mutates on the UI thread.
  bool is_fetching_;

  DISALLOW_COPY_AND_ASSIGN(BrowsingDataFileSystemHelperImpl);
};

BrowsingDataFileSystemHelperImpl::BrowsingDataFileSystemHelperImpl(
    fileapi::FileSystemContext* filesystem_context)
    : filesystem_context_(filesystem_context),
      is_fetching_(false) {
  DCHECK(filesystem_context_.get());
}

BrowsingDataFileSystemHelperImpl::~BrowsingDataFileSystemHelperImpl() {
}

void BrowsingDataFileSystemHelperImpl::StartFetching(
    const base::Callback<void(const std::list<FileSystemInfo>&)>& callback) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(!is_fetching_);
  DCHECK_EQ(false, callback.is_null());
  is_fetching_ = true;
  completion_callback_ = callback;
  file_task_runner()->PostTask(
      FROM_HERE,
      base::Bind(
          &BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread,
          this));
}

void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOrigin(
    const GURL& origin) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  file_task_runner()->PostTask(
      FROM_HERE,
      base::Bind(
          &BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread,
          this, origin));
}

void BrowsingDataFileSystemHelperImpl::FetchFileSystemInfoInFileThread() {
  DCHECK(file_task_runner()->RunsTasksOnCurrentThread());

  // We check usage for these filesystem types.
  const fileapi::FileSystemType types[] = {
    fileapi::kFileSystemTypeTemporary,
    fileapi::kFileSystemTypePersistent,
    fileapi::kFileSystemTypeSyncable,
  };

  typedef std::map<GURL, FileSystemInfo> OriginInfoMap;
  OriginInfoMap file_system_info_map;
  for (size_t i = 0; i < arraysize(types); ++i) {
    fileapi::FileSystemType type = types[i];
    fileapi::FileSystemQuotaUtil* quota_util =
      filesystem_context_->GetQuotaUtil(type);
    DCHECK(quota_util);
    std::set<GURL> origins;
    quota_util->GetOriginsForTypeOnFileTaskRunner(type, &origins);
    for (std::set<GURL>::iterator iter = origins.begin();
        iter != origins.end(); ++iter) {
      const GURL& current = *iter;
      if (!BrowsingDataHelper::HasWebScheme(current))
        continue;  // Non-websafe state is not considered browsing data.
      int64 usage = quota_util->GetOriginUsageOnFileTaskRunner(
          filesystem_context_.get(), current, type);
      OriginInfoMap::iterator inserted =
          file_system_info_map.insert(
              std::make_pair(current, FileSystemInfo(current))).first;
      inserted->second.usage_map[type] = usage;
    }
  }

  for (OriginInfoMap::iterator iter = file_system_info_map.begin();
       iter != file_system_info_map.end(); ++iter) {
    file_system_info_.push_back(iter->second);
  }

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&BrowsingDataFileSystemHelperImpl::NotifyOnUIThread, this));
}

void BrowsingDataFileSystemHelperImpl::NotifyOnUIThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(is_fetching_);
  completion_callback_.Run(file_system_info_);
  completion_callback_.Reset();
  is_fetching_ = false;
}

void BrowsingDataFileSystemHelperImpl::DeleteFileSystemOriginInFileThread(
    const GURL& origin) {
  DCHECK(file_task_runner()->RunsTasksOnCurrentThread());
  filesystem_context_->DeleteDataForOriginOnFileTaskRunner(origin);
}

}  // namespace

BrowsingDataFileSystemHelper::FileSystemInfo::FileSystemInfo(
    const GURL& origin) : origin(origin) {}

BrowsingDataFileSystemHelper::FileSystemInfo::~FileSystemInfo() {}

// static
BrowsingDataFileSystemHelper* BrowsingDataFileSystemHelper::Create(
    fileapi::FileSystemContext* filesystem_context) {
  return new BrowsingDataFileSystemHelperImpl(filesystem_context);
}

CannedBrowsingDataFileSystemHelper::CannedBrowsingDataFileSystemHelper(
    Profile* profile) {
}

CannedBrowsingDataFileSystemHelper::CannedBrowsingDataFileSystemHelper() {
}

CannedBrowsingDataFileSystemHelper::~CannedBrowsingDataFileSystemHelper() {}

CannedBrowsingDataFileSystemHelper*
    CannedBrowsingDataFileSystemHelper::Clone() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  CannedBrowsingDataFileSystemHelper* clone =
      new CannedBrowsingDataFileSystemHelper();
  // This list only mutates on the UI thread, so it's safe to work with it here
  // (given the DCHECK above).
  clone->file_system_info_ = file_system_info_;
  return clone;
}

void CannedBrowsingDataFileSystemHelper::AddFileSystem(
    const GURL& origin, const fileapi::FileSystemType type, const int64 size) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // This canned implementation of AddFileSystem uses an O(n^2) algorithm; which
  // is fine, as it isn't meant for use in a high-volume context. If it turns
  // out that we want to start using this in a context with many, many origins,
  // we should think about reworking the implementation.
  bool duplicate_origin = false;
  for (std::list<FileSystemInfo>::iterator
           file_system = file_system_info_.begin();
       file_system != file_system_info_.end();
       ++file_system) {
    if (file_system->origin == origin) {
      file_system->usage_map[type] = size;
      duplicate_origin = true;
      break;
    }
  }
  if (duplicate_origin)
    return;

  if (!BrowsingDataHelper::HasWebScheme(origin))
    return;  // Non-websafe state is not considered browsing data.

  FileSystemInfo info(origin);
  info.usage_map[type] = size;
  file_system_info_.push_back(info);
}

void CannedBrowsingDataFileSystemHelper::Reset() {
  file_system_info_.clear();
}

bool CannedBrowsingDataFileSystemHelper::empty() const {
  return file_system_info_.empty();
}

size_t CannedBrowsingDataFileSystemHelper::GetFileSystemCount() const {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  return file_system_info_.size();
}

void CannedBrowsingDataFileSystemHelper::StartFetching(
    const base::Callback<void(const std::list<FileSystemInfo>&)>& callback) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(!callback.is_null());

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE, base::Bind(callback, file_system_info_));
}
