// 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::Bind(&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_ = NULL;

  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::Bind(&ExampleWorker::DoWork, request_))) {
    NOTREACHED();
    request_ = NULL;
    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
