// 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 "storage/browser/blob/shareable_file_reference.h"

#include <map>

#include "base/lazy_instance.h"
#include "base/task_runner.h"
#include "base/threading/non_thread_safe.h"

namespace storage {

namespace {

// A shareable file map with enforcement of thread checker.
class ShareableFileMap : public base::NonThreadSafe {
 public:
  typedef std::map<base::FilePath, ShareableFileReference*> FileMap;
  typedef FileMap::iterator iterator;
  typedef FileMap::key_type key_type;
  typedef FileMap::value_type value_type;

  ShareableFileMap() {}

  ~ShareableFileMap() {
    DetachFromThread();
  }

  iterator Find(key_type key) {
    DCHECK(CalledOnValidThread());
    return file_map_.find(key);
  }

  iterator End() {
    DCHECK(CalledOnValidThread());
    return file_map_.end();
  }

  std::pair<iterator, bool> Insert(value_type value) {
    DCHECK(CalledOnValidThread());
    return file_map_.insert(value);
  }

  void Erase(key_type key) {
    DCHECK(CalledOnValidThread());
    file_map_.erase(key);
  }

 private:
  FileMap file_map_;
  DISALLOW_COPY_AND_ASSIGN(ShareableFileMap);
};

base::LazyInstance<ShareableFileMap> g_file_map = LAZY_INSTANCE_INITIALIZER;

}  // namespace

// static
scoped_refptr<ShareableFileReference> ShareableFileReference::Get(
    const base::FilePath& path) {
  ShareableFileMap::iterator found = g_file_map.Get().Find(path);
  ShareableFileReference* reference =
      (found == g_file_map.Get().End()) ? NULL : found->second;
  return scoped_refptr<ShareableFileReference>(reference);
}

// static
scoped_refptr<ShareableFileReference> ShareableFileReference::GetOrCreate(
    const base::FilePath& path,
    FinalReleasePolicy policy,
    base::TaskRunner* file_task_runner) {
  return GetOrCreate(
      ScopedFile(path, static_cast<ScopedFile::ScopeOutPolicy>(policy),
                 file_task_runner));
}

// static
scoped_refptr<ShareableFileReference> ShareableFileReference::GetOrCreate(
    ScopedFile scoped_file) {
  if (scoped_file.path().empty())
    return scoped_refptr<ShareableFileReference>();

  typedef std::pair<ShareableFileMap::iterator, bool> InsertResult;
  // Required for VS2010:
  // http://connect.microsoft.com/VisualStudio/feedback/
  // details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
  storage::ShareableFileReference* null_reference = NULL;
  InsertResult result = g_file_map.Get().Insert(
      ShareableFileMap::value_type(scoped_file.path(), null_reference));
  if (result.second == false) {
    scoped_file.Release();
    return scoped_refptr<ShareableFileReference>(result.first->second);
  }

  // Wasn't in the map, create a new reference and store the pointer.
  scoped_refptr<ShareableFileReference> reference(
      new ShareableFileReference(scoped_file.Pass()));
  result.first->second = reference.get();
  return reference;
}

void ShareableFileReference::AddFinalReleaseCallback(
    const FinalReleaseCallback& callback) {
  DCHECK(g_file_map.Get().CalledOnValidThread());
  scoped_file_.AddScopeOutCallback(callback, NULL);
}

ShareableFileReference::ShareableFileReference(ScopedFile scoped_file)
    : scoped_file_(scoped_file.Pass()) {
  DCHECK(g_file_map.Get().Find(path())->second == NULL);
}

ShareableFileReference::~ShareableFileReference() {
  DCHECK(g_file_map.Get().Find(path())->second == this);
  g_file_map.Get().Erase(path());
}

}  // namespace storage
