// Copyright (c) 2012 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.

#ifndef PPAPI_TESTS_TEST_UTILS_H_
#define PPAPI_TESTS_TEST_UTILS_H_

#include <string>

#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/message_loop.h"
#include "ppapi/utility/completion_callback_factory.h"

namespace pp {
class NetAddress;
}

// Timeout to wait for some action to complete.
extern const int kActionTimeoutMs;

const PPB_Testing_Private* GetTestingInterface();
std::string ReportError(const char* method, int32_t error);
void PlatformSleep(int duration_ms);
bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);

uint16_t ConvertFromNetEndian16(uint16_t x);
uint16_t ConvertToNetEndian16(uint16_t x);
bool EqualNetAddress(const pp::NetAddress& addr1, const pp::NetAddress& addr2);
// Only returns the first address if there are more than one available.
bool ResolveHost(PP_Instance instance,
                 const std::string& host,
                 uint16_t port,
                 pp::NetAddress* addr);
bool ReplacePort(PP_Instance instance,
                 const pp::NetAddress& input_addr,
                 uint16_t port,
                 pp::NetAddress* output_addr);
uint16_t GetPort(const pp::NetAddress& addr);

// NestedEvent allows you to run a nested MessageLoop and wait for a particular
// event to complete. For example, you can use it to wait for a callback on a
// PPP interface, which will "Signal" the event and make the loop quit.
// "Wait()" will return immediately if it has already been signalled. Otherwise,
// it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
// return only after it has been signalled.
// Example:
//  std::string TestFullscreen::TestNormalToFullscreen() {
//    pp::Fullscreen screen_mode(instance);
//    screen_mode.SetFullscreen(true);
//    SimulateUserGesture();
//    // Let DidChangeView run in a nested message loop.
//    nested_event_.Wait();
//    Pass();
//  }
//
//  void TestFullscreen::DidChangeView(const pp::View& view) {
//    nested_event_.Signal();
//  }
//
// All methods except Signal and PostSignal must be invoked on the main thread.
// It's OK to signal from a background thread, so you can (for example) Signal()
// from the Audio thread.
class NestedEvent {
 public:
  explicit NestedEvent(PP_Instance instance)
      : instance_(instance), waiting_(false), signalled_(false) {
  }
  // Run a nested message loop and wait until Signal() is called. If Signal()
  // has already been called, return immediately without running a nested loop.
  void Wait();
  // Signal the NestedEvent. If Wait() has been called, quit the message loop.
  // This can be called from any thread.
  void Signal();
  // Signal the NestedEvent in |wait_ms| milliseconds. This can be called from
  // any thread.
  void PostSignal(int32_t wait_ms);

  // Reset the NestedEvent so it can be used again.
  void Reset();
 private:
  void SignalOnMainThread();
  static void SignalThunk(void* async_event, int32_t result);

  PP_Instance instance_;
  bool waiting_;
  bool signalled_;
  // Disable copy and assign.
  NestedEvent(const NestedEvent&);
  NestedEvent& operator=(const NestedEvent&);
};

enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
class TestCompletionCallback {
 public:
  class Delegate {
   public:
    virtual ~Delegate() {}
    virtual void OnCallback(void* user_data, int32_t result) = 0;
  };
  explicit TestCompletionCallback(PP_Instance instance);
  // TODO(dmichael): Remove this constructor.
  TestCompletionCallback(PP_Instance instance, bool force_async);

  TestCompletionCallback(PP_Instance instance, CallbackType callback_type);

  // Sets a Delegate instance. OnCallback() of this instance will be invoked
  // when the completion callback is invoked.
  // The delegate will be reset when Reset() or GetCallback() is called.
  void SetDelegate(Delegate* delegate) { delegate_ = delegate; }

  // Wait for a result, given the return from the call which took this callback
  // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
  // block until its callback has been invoked (in some cases, this will already
  // have happened, and WaitForCallback can return immediately).
  // For any other values, WaitForResult will simply set its internal "result_"
  // field. To retrieve the final result of the operation (i.e., the result
  // the callback has run, if necessary), call result(). You can call result()
  // as many times as necessary until a new pp::CompletionCallback is retrieved.
  //
  // In some cases, you may want to check that the callback was invoked in the
  // expected way (i.e., if the callback was "Required", then it should be
  // invoked asynchronously). Within the body of a test (where returning a non-
  // empty string indicates test failure), you can use the
  // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
  // you can use failed() and errors().
  //
  // Example usage within a test:
  //  callback.WaitForResult(foo.DoSomething(callback));
  //  CHECK_CALLBACK_BEHAVIOR(callback);
  //  ASSERT_EQ(PP_OK, callback.result());
  //
  // Example usage within a helper function:
  //  void HelperFunction(std::string* error_message) {
  //    callback.WaitForResult(foo.DoSomething(callback));
  //    if (callback.failed())
  //      error_message->assign(callback.errors());
  //  }
  void WaitForResult(int32_t result);

  // Used when you expect to receive either synchronous completion with PP_OK
  // or a PP_ERROR_ABORTED asynchronously.
  //  Example usage:
  //  int32_t result = 0;
  //  {
  //    pp::URLLoader temp(instance_);
  //    result = temp.Open(request, callback);
  //  }
  //  callback.WaitForAbortResult(result);
  //  CHECK_CALLBACK_BEHAVIOR(callback);
  void WaitForAbortResult(int32_t result);

  // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
  // TestCompletionCallback.
  pp::CompletionCallback GetCallback();

  bool failed() { return !errors_.empty(); }
  const std::string& errors() { return errors_; }

  int32_t result() const { return result_; }

  // Reset so that this callback can be used again.
  void Reset();

  CallbackType callback_type() { return callback_type_; }
  void set_target_loop(const pp::MessageLoop& loop) { target_loop_ = loop; }
  static void Handler(void* user_data, int32_t result);

 protected:
  void RunMessageLoop();
  void QuitMessageLoop();

  // Used to check that WaitForResult is only called once for each usage of the
  // callback.
  bool wait_for_result_called_;
  // Indicates whether we have already been invoked.
  bool have_result_;
  // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
  int32_t result_;
  CallbackType callback_type_;
  bool post_quit_task_;
  std::string errors_;
  PP_Instance instance_;
  Delegate* delegate_;
  pp::MessageLoop target_loop_;
};

template <typename OutputT>
class TestCompletionCallbackWithOutput {
 public:
  explicit TestCompletionCallbackWithOutput(PP_Instance instance)
      : callback_(instance),
        output_storage_() {
    pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
  }

  TestCompletionCallbackWithOutput(PP_Instance instance, bool force_async)
      : callback_(instance, force_async),
        output_storage_() {
    pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
  }

  TestCompletionCallbackWithOutput(PP_Instance instance,
                                   CallbackType callback_type)
      : callback_(instance, callback_type),
        output_storage_() {
    pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
  }

  pp::CompletionCallbackWithOutput<OutputT> GetCallback();
  OutputT output() {
    return pp::internal::CallbackOutputTraits<OutputT>::StorageToPluginArg(
        output_storage_);
  }

  // Delegate functions to TestCompletionCallback
  void SetDelegate(TestCompletionCallback::Delegate* delegate) {
    callback_.SetDelegate(delegate);
  }
  void WaitForResult(int32_t result) { callback_.WaitForResult(result); }
  void WaitForAbortResult(int32_t result) {
    callback_.WaitForAbortResult(result);
  }
  bool failed() { return callback_.failed(); }
  const std::string& errors() { return callback_.errors(); }
  int32_t result() const { return callback_.result(); }
  void Reset() {
    pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
    return callback_.Reset();
  }

 private:
  TestCompletionCallback callback_;
  typename pp::CompletionCallbackWithOutput<OutputT>::OutputStorageType
      output_storage_;
};

template <typename OutputT>
pp::CompletionCallbackWithOutput<OutputT>
TestCompletionCallbackWithOutput<OutputT>::GetCallback() {
  this->Reset();
  if (callback_.callback_type() == PP_BLOCKING) {
    pp::CompletionCallbackWithOutput<OutputT> cc(&output_storage_);
    return cc;
  }

  callback_.set_target_loop(pp::MessageLoop::GetCurrent());
  pp::CompletionCallbackWithOutput<OutputT> cc(
      &TestCompletionCallback::Handler,
      this,
      &output_storage_);
  if (callback_.callback_type() == PP_OPTIONAL)
    cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
  return cc;
}

// Verifies that the callback didn't record any errors. If the callback is run
// in an unexpected way (e.g., if it's invoked asynchronously when the call
// should have blocked), this returns an appropriate error string.
#define CHECK_CALLBACK_BEHAVIOR(callback) \
do { \
  if ((callback).failed()) \
    return MakeFailureMessage(__FILE__, __LINE__, \
                              (callback).errors().c_str()); \
} while (false)

/*
 * A set of macros to use for platform detection. These were largely copied
 * from chromium's build_config.h.
 */
#if defined(__APPLE__)
#define PPAPI_OS_MACOSX 1
#elif defined(ANDROID)
#define PPAPI_OS_ANDROID 1
#elif defined(__native_client__)
#define PPAPI_OS_NACL 1
#elif defined(__linux__)
#define PPAPI_OS_LINUX 1
#elif defined(_WIN32)
#define PPAPI_OS_WIN 1
#elif defined(__FreeBSD__)
#define PPAPI_OS_FREEBSD 1
#elif defined(__OpenBSD__)
#define PPAPI_OS_OPENBSD 1
#elif defined(__sun)
#define PPAPI_OS_SOLARIS 1
#else
#error Please add support for your platform in ppapi/tests/test_utils.h
#endif

/* These are used to determine POSIX-like implementations vs Windows. */
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
    defined(__OpenBSD__) || defined(__sun) || defined(__native_client__)
#define PPAPI_POSIX 1
#endif

#endif  // PPAPI_TESTS_TEST_UTILS_H_
