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

// Illustrates how to use net::TestCompletionCallback.

#include "net/base/test_completion_callback.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/completion_once_callback.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace net {

namespace {

const int kMagicResult = 8888;

void CallClosureAfterCheckingResult(const base::Closure& closure,
                                    bool* did_check_result,
                                    int result) {
  DCHECK_EQ(result, kMagicResult);
  *did_check_result = true;
  closure.Run();
}

// ExampleEmployer is a toy version of HostResolver
// TODO: restore damage done in extracting example from real code
// (e.g. bring back real destructor, bring back comments)
class ExampleEmployer {
 public:
  ExampleEmployer();
  ~ExampleEmployer();

  // Posts to the current thread a task which itself posts |callback| to the
  // current thread. Returns true on success
  bool DoSomething(CompletionOnceCallback callback);

 private:
  class ExampleWorker;
  friend class ExampleWorker;
  scoped_refptr<ExampleWorker> request_;
  DISALLOW_COPY_AND_ASSIGN(ExampleEmployer);
};

// Helper class; this is how ExampleEmployer schedules work.
class ExampleEmployer::ExampleWorker
    : public base::RefCountedThreadSafe<ExampleWorker> {
 public:
  ExampleWorker(ExampleEmployer* employer, CompletionOnceCallback callback)
      : employer_(employer), callback_(std::move(callback)) {}
  void DoWork();
  void DoCallback();
 private:
  friend class base::RefCountedThreadSafe<ExampleWorker>;

  ~ExampleWorker() = default;

  // Only used on the origin thread (where DoSomething was called).
  ExampleEmployer* employer_;
  CompletionOnceCallback callback_;
  // Used to post ourselves onto the origin thread.
  const scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_ =
      base::ThreadTaskRunnerHandle::Get();
};

void ExampleEmployer::ExampleWorker::DoWork() {
  // In a real worker thread, some work would be done here.
  // Pretend it is, and send the completion callback.
  origin_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&ExampleWorker::DoCallback, this));
}

void ExampleEmployer::ExampleWorker::DoCallback() {
  // Running on the origin thread.

  // Drop the employer_'s reference to us.  Do this before running the
  // callback since the callback might result in the employer being
  // destroyed.
  employer_->request_ = nullptr;

  std::move(callback_).Run(kMagicResult);
}

ExampleEmployer::ExampleEmployer() = default;

ExampleEmployer::~ExampleEmployer() = default;

bool ExampleEmployer::DoSomething(CompletionOnceCallback callback) {
  DCHECK(!request_.get()) << "already in use";

  request_ = new ExampleWorker(this, std::move(callback));

  if (!base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&ExampleWorker::DoWork, request_))) {
    NOTREACHED();
    request_ = nullptr;
    return false;
  }

  return true;
}

}  // namespace

class TestCompletionCallbackTest : public PlatformTest,
                                   public WithScopedTaskEnvironment {};

TEST_F(TestCompletionCallbackTest, Simple) {
  ExampleEmployer boss;
  TestCompletionCallback callback;
  bool queued = boss.DoSomething(callback.callback());
  EXPECT_TRUE(queued);
  int result = callback.WaitForResult();
  EXPECT_EQ(result, kMagicResult);
}

TEST_F(TestCompletionCallbackTest, Closure) {
  ExampleEmployer boss;
  TestClosure closure;
  bool did_check_result = false;
  CompletionOnceCallback completion_callback =
      base::BindOnce(&CallClosureAfterCheckingResult, closure.closure(),
                     base::Unretained(&did_check_result));
  bool queued = boss.DoSomething(std::move(completion_callback));
  EXPECT_TRUE(queued);

  EXPECT_FALSE(did_check_result);
  closure.WaitForResult();
  EXPECT_TRUE(did_check_result);
}

// TODO: test deleting ExampleEmployer while work outstanding

}  // namespace net
