// 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_scheduler/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
