// Copyright (c) 2011 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 "base/memory/ref_counted.h"
#include "base/task.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class CancelInDestructor : public base::RefCounted<CancelInDestructor> {
 public:
  CancelInDestructor() : cancelable_task_(NULL) {}

  void Start() {
    if (cancelable_task_) {
      ADD_FAILURE();
      return;
    }
    AddRef();
    cancelable_task_ = NewRunnableMethod(
        this, &CancelInDestructor::NeverIssuedCallback);
    Release();
  }

  CancelableTask* cancelable_task() {
    return cancelable_task_;
  }

 private:
  friend class base::RefCounted<CancelInDestructor>;

  ~CancelInDestructor() {
    if (cancelable_task_)
      cancelable_task_->Cancel();
  }

  void NeverIssuedCallback() { NOTREACHED(); }

  CancelableTask* cancelable_task_;
};

TEST(TaskTest, TestCancelInDestructor) {
  // Intentionally not using a scoped_refptr for cancel_in_destructor.
  CancelInDestructor* cancel_in_destructor = new CancelInDestructor();
  cancel_in_destructor->Start();
  CancelableTask* cancelable_task = cancel_in_destructor->cancelable_task();
  ASSERT_TRUE(cancelable_task);
  delete cancelable_task;
}

class DoneTask : public Task {
 public:
  DoneTask(int* run_count, bool* was_deleted)
      : run_count_(run_count), was_deleted_(was_deleted) {
  }
  virtual ~DoneTask() {
    *was_deleted_ = true;
  }

  virtual void Run() {
    ++(*run_count_);
  }

  int* run_count_;
  bool* was_deleted_;
};

TEST(TaskTest, TestScopedTaskRunnerExitScope) {
  int run_count = 0;
  bool was_deleted = false;
  {
    base::ScopedTaskRunner runner(new DoneTask(&run_count, &was_deleted));
    EXPECT_EQ(0, run_count);
  }
  EXPECT_EQ(1, run_count);
  EXPECT_TRUE(was_deleted);
}

TEST(TaskTest, TestScopedTaskRunnerRelease) {
  int run_count = 0;
  bool was_deleted = false;
  {
    base::ScopedTaskRunner runner(new DoneTask(&run_count, &was_deleted));
    delete runner.Release();
    EXPECT_TRUE(was_deleted);
  }
  EXPECT_EQ(0, run_count);
}

TEST(TaskTest, TestScopedTaskRunnerManualRun) {
  int run_count = 0;
  Task* done_task = NULL;
  bool was_deleted = false;
  {
    base::ScopedTaskRunner runner(new DoneTask(&run_count, &was_deleted));
    done_task = runner.Release();
    EXPECT_TRUE(NULL != done_task);
    EXPECT_FALSE(was_deleted);
    EXPECT_EQ(0, run_count);
    done_task->Run();
    EXPECT_FALSE(was_deleted);
    EXPECT_EQ(1, run_count);
  }
  EXPECT_EQ(1, run_count);
  delete done_task;
  EXPECT_TRUE(was_deleted);
}

}  // namespace
