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

#include "extensions/test/extension_test_message_listener.h"

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/test/test_api.h"
#include "extensions/browser/notification_types.h"

ExtensionTestMessageListener::ExtensionTestMessageListener(
    const std::string& expected_message,
    bool will_reply)
    : expected_message_(expected_message),
      satisfied_(false),
      waiting_(false),
      wait_for_any_message_(false),
      will_reply_(will_reply),
      replied_(false),
      failed_(false) {
  registrar_.Add(this,
                 extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE,
                 content::NotificationService::AllSources());
}

ExtensionTestMessageListener::ExtensionTestMessageListener(bool will_reply)
    : satisfied_(false),
      waiting_(false),
      wait_for_any_message_(true),
      will_reply_(will_reply),
      replied_(false),
      failed_(false) {
  registrar_.Add(this,
                 extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE,
                 content::NotificationService::AllSources());
}

ExtensionTestMessageListener::~ExtensionTestMessageListener() {}

bool ExtensionTestMessageListener::WaitUntilSatisfied()  {
  if (satisfied_)
    return !failed_;
  waiting_ = true;
  content::RunMessageLoop();
  return !failed_;
}

void ExtensionTestMessageListener::Reply(const std::string& message) {
  CHECK(satisfied_);
  CHECK(!replied_);

  replied_ = true;
  function_->Reply(message);
  function_ = NULL;
}

void ExtensionTestMessageListener::Reply(int message) {
  Reply(base::IntToString(message));
}

void ExtensionTestMessageListener::ReplyWithError(const std::string& error) {
  CHECK(satisfied_);
  CHECK(!replied_);

  replied_ = true;
  function_->ReplyWithError(error);
  function_ = NULL;
}

void ExtensionTestMessageListener::Reset() {
  satisfied_ = false;
  failed_ = false;
  message_.clear();
  replied_ = false;
}

void ExtensionTestMessageListener::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE, type);

  // Return immediately if we're already satisfied or it's not the right
  // extension.
  extensions::TestSendMessageFunction* function =
      content::Source<extensions::TestSendMessageFunction>(source).ptr();
  if (satisfied_ ||
      (!extension_id_.empty() && function->extension_id() != extension_id_)) {
    return;
  }

  // We should have an empty message if we're not already satisfied.
  CHECK(message_.empty());

  std::pair<std::string, bool*>* message_details =
      content::Details<std::pair<std::string, bool*>>(details).ptr();
  const std::string& message = message_details->first;
  if (message == expected_message_ || wait_for_any_message_ ||
      (!failure_message_.empty() && message == failure_message_)) {
    // We always reply to the message we were waiting for, even if it's just an
    // empty string.
    *message_details->second = true;
    message_ = message;
    satisfied_ = true;
    failed_ = (message_ == failure_message_);

    // Reply immediately, or save the function for future use.
    function_ = function;
    if (!will_reply_)
      Reply(std::string());

    if (waiting_) {
      waiting_ = false;
      base::MessageLoopForUI::current()->QuitWhenIdle();
    }
  }
}
