// 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 "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_callback.h"
#include "net/base/test_completion_callback.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(const CompletionCallback& 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, const CompletionCallback& callback)
      : employer_(employer), callback_(callback) {}
  void DoWork();
  void DoCallback();
 private:
  friend class base::RefCountedThreadSafe<ExampleWorker>;

  ~ExampleWorker() {}

  // Only used on the origin thread (where DoSomething was called).
  ExampleEmployer* employer_;
  CompletionCallback 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;

  callback_.Run(kMagicResult);
}

ExampleEmployer::ExampleEmployer() {
}

ExampleEmployer::~ExampleEmployer() {
}

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

  request_ = new ExampleWorker(this, callback);

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

  return true;
}

}  // namespace

typedef PlatformTest TestCompletionCallbackTest;

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;
  CompletionCallback completion_callback =
      base::Bind(&CallClosureAfterCheckingResult, closure.closure(),
                 base::Unretained(&did_check_result));
  bool queued = boss.DoSomething(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
