// Copyright (c) 2017 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.

// Internal helper used to sequence cleanup and reuse of cache directories
// among different objects.

#include "net/disk_cache/backend_cleanup_tracker.h"

#include <unordered_map>
#include <utility>

#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"

namespace disk_cache {

namespace {

using TrackerMap = std::unordered_map<base::FilePath, BackendCleanupTracker*>;
struct AllBackendCleanupTrackers {
  TrackerMap map;

  // Since clients can potentially call CreateCacheBackend from multiple
  // threads, we need to lock the map keeping track of cleanup trackers
  // for these backends. Our overall strategy is to have TryCreate
  // acts as an arbitrator --- whatever thread grabs one, gets to operate
  // on the tracker freely until it gets destroyed.
  base::Lock lock;
};

static base::LazyInstance<AllBackendCleanupTrackers>::Leaky g_all_trackers;

}  // namespace.

// static
scoped_refptr<BackendCleanupTracker> BackendCleanupTracker::TryCreate(
    const base::FilePath& path,
    base::OnceClosure retry_closure) {
  AllBackendCleanupTrackers* all_trackers = g_all_trackers.Pointer();
  base::AutoLock lock(all_trackers->lock);

  std::pair<TrackerMap::iterator, bool> insert_result =
      all_trackers->map.insert(
          std::pair<base::FilePath, BackendCleanupTracker*>(path, nullptr));
  if (insert_result.second) {
    insert_result.first->second = new BackendCleanupTracker(path);
    return insert_result.first->second;
  } else {
    insert_result.first->second->AddPostCleanupCallbackImpl(
        std::move(retry_closure));
    return nullptr;
  }
}

void BackendCleanupTracker::AddPostCleanupCallback(base::OnceClosure cb) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(seq_checker_);
  // Despite the sequencing requirement we need to grab the table lock since
  // this may otherwise race against TryMakeContext.
  base::AutoLock lock(g_all_trackers.Get().lock);
  AddPostCleanupCallbackImpl(std::move(cb));
}

void BackendCleanupTracker::AddPostCleanupCallbackImpl(base::OnceClosure cb) {
  post_cleanup_cbs_.push_back(
      std::make_pair(base::SequencedTaskRunnerHandle::Get(), std::move(cb)));
}

BackendCleanupTracker::BackendCleanupTracker(const base::FilePath& path)
    : path_(path) {}

BackendCleanupTracker::~BackendCleanupTracker() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(seq_checker_);

  {
    AllBackendCleanupTrackers* all_trackers = g_all_trackers.Pointer();
    base::AutoLock lock(all_trackers->lock);
    int rv = all_trackers->map.erase(path_);
    DCHECK_EQ(1, rv);
  }

  while (!post_cleanup_cbs_.empty()) {
    post_cleanup_cbs_.back().first->PostTask(
        FROM_HERE, std::move(post_cleanup_cbs_.back().second));
    post_cleanup_cbs_.pop_back();
  }
}

}  // namespace disk_cache
