// Copyright 2013 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 "content/child/fileapi/webfilesystem_impl.h"

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_local.h"
#include "content/child/child_thread.h"
#include "content/child/file_info_util.h"
#include "content/child/fileapi/file_system_dispatcher.h"
#include "content/child/fileapi/webfilewriter_impl.h"
#include "content/child/worker_task_runner.h"
#include "content/common/fileapi/file_system_messages.h"
#include "third_party/WebKit/public/platform/WebFileInfo.h"
#include "third_party/WebKit/public/platform/WebFileSystemCallbacks.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebHeap.h"
#include "url/gurl.h"
#include "webkit/common/fileapi/directory_entry.h"
#include "webkit/common/fileapi/file_system_util.h"

using blink::WebFileInfo;
using blink::WebFileSystemCallbacks;
using blink::WebFileSystemEntry;
using blink::WebString;
using blink::WebURL;
using blink::WebVector;

namespace content {

class WebFileSystemImpl::WaitableCallbackResults
    : public base::RefCountedThreadSafe<WaitableCallbackResults> {
 public:
  WaitableCallbackResults()
      : results_available_event_(true /* manual_reset */,
                                 false /* initially_signaled */) {}

  void AddResultsAndSignal(const base::Closure& results_closure) {
    base::AutoLock lock(lock_);
    results_closures_.push_back(results_closure);
    results_available_event_.Signal();
  }

  void WaitAndRun() {
    {
      blink::WebHeap::SafePointScope safe_point;
      results_available_event_.Wait();
    }
    Run();
  }

  void Run() {
    std::vector<base::Closure> closures;
    {
      base::AutoLock lock(lock_);
      results_closures_.swap(closures);
      results_available_event_.Reset();
    }
    for (size_t i = 0; i < closures.size(); ++i)
      closures[i].Run();
  }

 private:
  friend class base::RefCountedThreadSafe<WaitableCallbackResults>;

  ~WaitableCallbackResults() {}

  base::Lock lock_;
  base::WaitableEvent results_available_event_;
  std::vector<base::Closure> results_closures_;
  DISALLOW_COPY_AND_ASSIGN(WaitableCallbackResults);
};

namespace {

typedef WebFileSystemImpl::WaitableCallbackResults WaitableCallbackResults;

base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl> >::Leaky
    g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER;

void DidReceiveSnapshotFile(int request_id) {
  if (ChildThread::current())
    ChildThread::current()->Send(
        new FileSystemHostMsg_DidReceiveSnapshotFile(request_id));
}

int CurrentWorkerId() {
  return WorkerTaskRunner::Instance()->CurrentWorkerId();
}

template <typename Method, typename Params>
void CallDispatcherOnMainThread(
    base::MessageLoopProxy* loop,
    Method method, const Params& params,
    WaitableCallbackResults* waitable_results) {
  if (!loop->RunsTasksOnCurrentThread()) {
    loop->PostTask(FROM_HERE,
                   base::Bind(&CallDispatcherOnMainThread<Method, Params>,
                              make_scoped_refptr(loop), method, params,
                              scoped_refptr<WaitableCallbackResults>()));
    if (!waitable_results)
      return;
    waitable_results->WaitAndRun();
  }
  if (!ChildThread::current() ||
      !ChildThread::current()->file_system_dispatcher())
    return;

  DCHECK(!waitable_results);
  DispatchToMethod(ChildThread::current()->file_system_dispatcher(),
                   method, params);
}

enum CallbacksUnregisterMode {
  UNREGISTER_CALLBACKS,
  DO_NOT_UNREGISTER_CALLBACKS,
};

// Bridging functions that convert the arguments into Blink objects
// (e.g. WebFileInfo, WebString, WebVector<WebFileSystemEntry>)
// and call WebFileSystemCallbacks's methods.
// These are called by RunCallbacks after crossing threads to ensure
// thread safety, because the Blink objects cannot be passed across
// threads by base::Bind().
void DidSucceed(WebFileSystemCallbacks* callbacks) {
  callbacks->didSucceed();
}

void DidReadMetadata(const base::File::Info& file_info,
                     WebFileSystemCallbacks* callbacks) {
  WebFileInfo web_file_info;
  FileInfoToWebFileInfo(file_info, &web_file_info);
  callbacks->didReadMetadata(web_file_info);
}

void DidReadDirectory(const std::vector<storage::DirectoryEntry>& entries,
                      bool has_more,
                      WebFileSystemCallbacks* callbacks) {
  WebVector<WebFileSystemEntry> file_system_entries(entries.size());
  for (size_t i = 0; i < entries.size(); ++i) {
    file_system_entries[i].name =
        base::FilePath(entries[i].name).AsUTF16Unsafe();
    file_system_entries[i].isDirectory = entries[i].is_directory;
  }
  callbacks->didReadDirectory(file_system_entries, has_more);
}

void DidOpenFileSystem(const base::string16& name, const GURL& root,
                       WebFileSystemCallbacks* callbacks) {
  callbacks->didOpenFileSystem(name, root);
}

void DidResolveURL(const base::string16& name,
                   const GURL& root_url,
                   storage::FileSystemType mount_type,
                   const base::string16& file_path,
                   bool is_directory,
                   WebFileSystemCallbacks* callbacks) {
  callbacks->didResolveURL(
      name,
      root_url,
      static_cast<blink::WebFileSystemType>(mount_type),
      file_path,
      is_directory);
}

void DidFail(base::File::Error error, WebFileSystemCallbacks* callbacks) {
  callbacks->didFail(storage::FileErrorToWebFileError(error));
}

// Run WebFileSystemCallbacks's |method| with |params|.
void RunCallbacks(
    int callbacks_id,
    const base::Callback<void(WebFileSystemCallbacks*)>& callback,
    CallbacksUnregisterMode callbacks_unregister_mode) {
  WebFileSystemImpl* filesystem =
      WebFileSystemImpl::ThreadSpecificInstance(NULL);
  if (!filesystem)
    return;
  WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
  if (callbacks_unregister_mode == UNREGISTER_CALLBACKS)
    filesystem->UnregisterCallbacks(callbacks_id);
  callback.Run(&callbacks);
}

void DispatchResultsClosure(int thread_id, int callbacks_id,
                            WaitableCallbackResults* waitable_results,
                            const base::Closure& results_closure) {
  if (thread_id != CurrentWorkerId()) {
    if (waitable_results) {
      // If someone is waiting, this should result in running the closure.
      waitable_results->AddResultsAndSignal(results_closure);
      // In case no one is waiting, post a task to run the closure.
      WorkerTaskRunner::Instance()->PostTask(
          thread_id,
          base::Bind(&WaitableCallbackResults::Run,
                     make_scoped_refptr(waitable_results)));
      return;
    }
    WorkerTaskRunner::Instance()->PostTask(thread_id, results_closure);
    return;
  }
  results_closure.Run();
}

void CallbackFileSystemCallbacks(
    int thread_id, int callbacks_id,
    WaitableCallbackResults* waitable_results,
    const base::Callback<void(WebFileSystemCallbacks*)>& callback,
    CallbacksUnregisterMode callbacksunregister_mode) {
  DispatchResultsClosure(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&RunCallbacks, callbacks_id, callback,
                 callbacksunregister_mode));
}

//-----------------------------------------------------------------------------
// Callback adapters. Callbacks must be called on the original calling thread,
// so these callback adapters relay back the results to the calling thread
// if necessary.

void OpenFileSystemCallbackAdapter(
    int thread_id, int callbacks_id,
    WaitableCallbackResults* waitable_results,
    const std::string& name, const GURL& root) {
  CallbackFileSystemCallbacks(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&DidOpenFileSystem, base::UTF8ToUTF16(name), root),
      UNREGISTER_CALLBACKS);
}

void ResolveURLCallbackAdapter(int thread_id,
                               int callbacks_id,
                               WaitableCallbackResults* waitable_results,
                               const storage::FileSystemInfo& info,
                               const base::FilePath& file_path,
                               bool is_directory) {
  base::FilePath normalized_path(
      storage::VirtualPath::GetNormalizedFilePath(file_path));
  CallbackFileSystemCallbacks(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&DidResolveURL, base::UTF8ToUTF16(info.name), info.root_url,
                 info.mount_type,
                 normalized_path.AsUTF16Unsafe(), is_directory),
      UNREGISTER_CALLBACKS);
}

void StatusCallbackAdapter(int thread_id, int callbacks_id,
                           WaitableCallbackResults* waitable_results,
                           base::File::Error error) {
  if (error == base::File::FILE_OK) {
    CallbackFileSystemCallbacks(
        thread_id, callbacks_id, waitable_results,
        base::Bind(&DidSucceed),
        UNREGISTER_CALLBACKS);
  } else {
    CallbackFileSystemCallbacks(
        thread_id, callbacks_id, waitable_results,
        base::Bind(&DidFail, error),
        UNREGISTER_CALLBACKS);
  }
}

void ReadMetadataCallbackAdapter(int thread_id, int callbacks_id,
                                 WaitableCallbackResults* waitable_results,
                                 const base::File::Info& file_info) {
  CallbackFileSystemCallbacks(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&DidReadMetadata, file_info),
      UNREGISTER_CALLBACKS);
}

void ReadDirectoryCallbackAdapter(
    int thread_id,
    int callbacks_id,
    WaitableCallbackResults* waitable_results,
    const std::vector<storage::DirectoryEntry>& entries,
    bool has_more) {
  CallbackFileSystemCallbacks(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&DidReadDirectory, entries, has_more),
      has_more ? DO_NOT_UNREGISTER_CALLBACKS : UNREGISTER_CALLBACKS);
}

void DidCreateFileWriter(
    int callbacks_id,
    const GURL& path,
    blink::WebFileWriterClient* client,
    base::MessageLoopProxy* main_thread_loop,
    const base::File::Info& file_info) {
  WebFileSystemImpl* filesystem =
      WebFileSystemImpl::ThreadSpecificInstance(NULL);
  if (!filesystem)
    return;

  WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
  filesystem->UnregisterCallbacks(callbacks_id);

  if (file_info.is_directory || file_info.size < 0) {
    callbacks.didFail(blink::WebFileErrorInvalidState);
    return;
  }
  WebFileWriterImpl::Type type =
      callbacks.shouldBlockUntilCompletion() ?
          WebFileWriterImpl::TYPE_SYNC : WebFileWriterImpl::TYPE_ASYNC;
  callbacks.didCreateFileWriter(
      new WebFileWriterImpl(path, client, type, main_thread_loop),
      file_info.size);
}

void CreateFileWriterCallbackAdapter(
    int thread_id, int callbacks_id,
    WaitableCallbackResults* waitable_results,
    base::MessageLoopProxy* main_thread_loop,
    const GURL& path,
    blink::WebFileWriterClient* client,
    const base::File::Info& file_info) {
  DispatchResultsClosure(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&DidCreateFileWriter, callbacks_id, path, client,
                 make_scoped_refptr(main_thread_loop), file_info));
}

void DidCreateSnapshotFile(
    int callbacks_id,
    base::MessageLoopProxy* main_thread_loop,
    const base::File::Info& file_info,
    const base::FilePath& platform_path,
    int request_id) {
  WebFileSystemImpl* filesystem =
      WebFileSystemImpl::ThreadSpecificInstance(NULL);
  if (!filesystem)
    return;

  WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
  filesystem->UnregisterCallbacks(callbacks_id);

  WebFileInfo web_file_info;
  FileInfoToWebFileInfo(file_info, &web_file_info);
  web_file_info.platformPath = platform_path.AsUTF16Unsafe();
  callbacks.didCreateSnapshotFile(web_file_info);

  // TODO(michaeln,kinuko): Use ThreadSafeSender when Blob becomes
  // non-bridge model.
  main_thread_loop->PostTask(
      FROM_HERE, base::Bind(&DidReceiveSnapshotFile, request_id));
}

void CreateSnapshotFileCallbackAdapter(
    int thread_id, int callbacks_id,
    WaitableCallbackResults* waitable_results,
    base::MessageLoopProxy* main_thread_loop,
    const base::File::Info& file_info,
    const base::FilePath& platform_path,
    int request_id) {
  DispatchResultsClosure(
      thread_id, callbacks_id, waitable_results,
      base::Bind(&DidCreateSnapshotFile, callbacks_id,
                 make_scoped_refptr(main_thread_loop),
                 file_info, platform_path, request_id));
}

}  // namespace

//-----------------------------------------------------------------------------
// WebFileSystemImpl

WebFileSystemImpl* WebFileSystemImpl::ThreadSpecificInstance(
    base::MessageLoopProxy* main_thread_loop) {
  if (g_webfilesystem_tls.Pointer()->Get() || !main_thread_loop)
    return g_webfilesystem_tls.Pointer()->Get();
  WebFileSystemImpl* filesystem = new WebFileSystemImpl(main_thread_loop);
  if (WorkerTaskRunner::Instance()->CurrentWorkerId())
    WorkerTaskRunner::Instance()->AddStopObserver(filesystem);
  return filesystem;
}

void WebFileSystemImpl::DeleteThreadSpecificInstance() {
  DCHECK(!WorkerTaskRunner::Instance()->CurrentWorkerId());
  if (g_webfilesystem_tls.Pointer()->Get())
    delete g_webfilesystem_tls.Pointer()->Get();
}

WebFileSystemImpl::WebFileSystemImpl(base::MessageLoopProxy* main_thread_loop)
    : main_thread_loop_(main_thread_loop),
      next_callbacks_id_(1) {
  g_webfilesystem_tls.Pointer()->Set(this);
}

WebFileSystemImpl::~WebFileSystemImpl() {
  g_webfilesystem_tls.Pointer()->Set(NULL);
}

void WebFileSystemImpl::OnWorkerRunLoopStopped() {
  delete this;
}

void WebFileSystemImpl::openFileSystem(
    const blink::WebURL& storage_partition,
    blink::WebFileSystemType type,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::OpenFileSystem,
      MakeTuple(GURL(storage_partition),
                static_cast<storage::FileSystemType>(type),
                base::Bind(&OpenFileSystemCallbackAdapter,
                           CurrentWorkerId(),
                           callbacks_id,
                           waitable_results),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(),
                           callbacks_id,
                           waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::resolveURL(
    const blink::WebURL& filesystem_url,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::ResolveURL,
      MakeTuple(GURL(filesystem_url),
                base::Bind(&ResolveURLCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::deleteFileSystem(
    const blink::WebURL& storage_partition,
    blink::WebFileSystemType type,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::DeleteFileSystem,
      MakeTuple(GURL(storage_partition),
                static_cast<storage::FileSystemType>(type),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(),
                           callbacks_id,
                           waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::move(
    const blink::WebURL& src_path,
    const blink::WebURL& dest_path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::Move,
      MakeTuple(GURL(src_path), GURL(dest_path),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::copy(
    const blink::WebURL& src_path,
    const blink::WebURL& dest_path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::Copy,
      MakeTuple(GURL(src_path), GURL(dest_path),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::remove(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::Remove,
      MakeTuple(GURL(path), false /* recursive */,
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::removeRecursively(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::Remove,
      MakeTuple(GURL(path), true /* recursive */,
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::readMetadata(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::ReadMetadata,
      MakeTuple(GURL(path),
                base::Bind(&ReadMetadataCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::createFile(
    const blink::WebURL& path,
    bool exclusive,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::CreateFile,
      MakeTuple(GURL(path), exclusive,
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::createDirectory(
    const blink::WebURL& path,
    bool exclusive,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::CreateDirectory,
      MakeTuple(GURL(path), exclusive, false /* recursive */,
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::fileExists(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::Exists,
      MakeTuple(GURL(path), false /* directory */,
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::directoryExists(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::Exists,
      MakeTuple(GURL(path), true /* directory */,
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

int WebFileSystemImpl::readDirectory(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::ReadDirectory,
      MakeTuple(GURL(path),
                base::Bind(&ReadDirectoryCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
  return callbacks_id;
}

void WebFileSystemImpl::createFileWriter(
    const WebURL& path,
    blink::WebFileWriterClient* client,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::ReadMetadata,
      MakeTuple(GURL(path),
                base::Bind(&CreateFileWriterCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results,
                           main_thread_loop_, GURL(path), client),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

void WebFileSystemImpl::createSnapshotFileAndReadMetadata(
    const blink::WebURL& path,
    WebFileSystemCallbacks callbacks) {
  int callbacks_id = RegisterCallbacks(callbacks);
  scoped_refptr<WaitableCallbackResults> waitable_results =
      MaybeCreateWaitableResults(callbacks, callbacks_id);
  CallDispatcherOnMainThread(
      main_thread_loop_.get(),
      &FileSystemDispatcher::CreateSnapshotFile,
      MakeTuple(GURL(path),
                base::Bind(&CreateSnapshotFileCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results,
                           main_thread_loop_),
                base::Bind(&StatusCallbackAdapter,
                           CurrentWorkerId(), callbacks_id, waitable_results)),
      waitable_results.get());
}

bool WebFileSystemImpl::waitForAdditionalResult(int callbacksId) {
  WaitableCallbackResultsMap::iterator found =
      waitable_results_.find(callbacksId);
  if (found == waitable_results_.end())
    return false;

  found->second->WaitAndRun();
  return true;
}

int WebFileSystemImpl::RegisterCallbacks(
    const WebFileSystemCallbacks& callbacks) {
  DCHECK(CalledOnValidThread());
  int id = next_callbacks_id_++;
  callbacks_[id] = callbacks;
  return id;
}

WebFileSystemCallbacks WebFileSystemImpl::GetCallbacks(int callbacks_id) {
  DCHECK(CalledOnValidThread());
  CallbacksMap::iterator found = callbacks_.find(callbacks_id);
  DCHECK(found != callbacks_.end());
  return found->second;
}

void WebFileSystemImpl::UnregisterCallbacks(int callbacks_id) {
  DCHECK(CalledOnValidThread());
  CallbacksMap::iterator found = callbacks_.find(callbacks_id);
  DCHECK(found != callbacks_.end());
  callbacks_.erase(found);

  waitable_results_.erase(callbacks_id);
}

WaitableCallbackResults* WebFileSystemImpl::MaybeCreateWaitableResults(
    const WebFileSystemCallbacks& callbacks, int callbacks_id) {
  if (!callbacks.shouldBlockUntilCompletion())
    return NULL;
  WaitableCallbackResults* results = new WaitableCallbackResults();
  waitable_results_[callbacks_id] = results;
  return results;
}

}  // namespace content
