// 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 "chrome/test/nacl/nacl_browsertest_util.h"

#include <stdlib.h>
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/values.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/nacl/common/nacl_switches.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/common/switches.h"

typedef content::TestMessageHandler::MessageResponse MessageResponse;

MessageResponse StructuredMessageHandler::HandleMessage(
    const std::string& json) {
  base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS);
  // Automation messages are stringified before they are sent because the
  // automation channel cannot handle arbitrary objects.  This means we
  // need to decode the json twice to get the original message.
  std::unique_ptr<base::Value> value = reader.ReadToValue(json);
  if (!value.get())
    return InternalError("Could parse automation JSON: " + json +
                         " because " + reader.GetErrorMessage());

  std::string temp;
  if (!value->GetAsString(&temp))
    return InternalError("Message was not a string: " + json);

  value = reader.ReadToValue(temp);
  if (!value.get())
    return InternalError("Could not parse message JSON: " + temp +
                         " because " + reader.GetErrorMessage());

  base::DictionaryValue* msg;
  if (!value->GetAsDictionary(&msg))
    return InternalError("Message was not an object: " + temp);

  std::string type;
  if (!msg->GetString("type", &type))
    return MissingField("unknown", "type");

  return HandleStructuredMessage(type, msg);
}

MessageResponse StructuredMessageHandler::MissingField(
    const std::string& type,
    const std::string& field) {
  return InternalError(type + " message did not have field: " + field);
}

MessageResponse StructuredMessageHandler::InternalError(
    const std::string& reason) {
  SetError(reason);
  return DONE;
}

LoadTestMessageHandler::LoadTestMessageHandler()
    : test_passed_(false) {
}

void LoadTestMessageHandler::Log(const std::string& type,
                                 const std::string& message) {
  // TODO(ncbray) better logging.
  LOG(INFO) << type << " " << message;
}

MessageResponse LoadTestMessageHandler::HandleStructuredMessage(
   const std::string& type,
   base::DictionaryValue* msg) {
  if (type == "Log") {
    std::string message;
    if (!msg->GetString("message", &message))
      return MissingField(type, "message");
    Log("LOG", message);
    return CONTINUE;
  } else if (type == "Shutdown") {
    std::string message;
    if (!msg->GetString("message", &message))
      return MissingField(type, "message");
    if (!msg->GetBoolean("passed", &test_passed_))
      return MissingField(type, "passed");
    Log("SHUTDOWN", message);
    return DONE;
  } else {
    return InternalError("Unknown message type: " + type);
  }
}

// A message handler for nacl_integration tests ported to be browser_tests.
// nacl_integration tests report to their test jig using a series of RPC calls
// that are encoded as URL requests. When these tests run as browser_tests,
// they make the same RPC requests, but use the automation channel instead of
// URL requests. This message handler decodes and responds to these requests.
class NaClIntegrationMessageHandler : public StructuredMessageHandler {
 public:
  NaClIntegrationMessageHandler();

  void Log(const std::string& message);

  MessageResponse HandleStructuredMessage(const std::string& type,
                                          base::DictionaryValue* msg) override;

  bool test_passed() const {
    return test_passed_;
  }

 private:
  bool test_passed_;

  DISALLOW_COPY_AND_ASSIGN(NaClIntegrationMessageHandler);
};

NaClIntegrationMessageHandler::NaClIntegrationMessageHandler()
    : test_passed_(false) {
}

void NaClIntegrationMessageHandler::Log(const std::string& message) {
  // TODO(ncbray) better logging.
  LOG(INFO) << "|||| " << message;
}

MessageResponse NaClIntegrationMessageHandler::HandleStructuredMessage(
    const std::string& type,
    base::DictionaryValue* msg) {
  if (type == "TestLog") {
    std::string message;
    if (!msg->GetString("message", &message))
      return MissingField(type, "message");
    Log(message);
    return CONTINUE;
  } else if (type == "Shutdown") {
    std::string message;
    if (!msg->GetString("message", &message))
      return MissingField(type, "message");
    if (!msg->GetBoolean("passed", &test_passed_))
      return MissingField(type, "passed");
    Log(message);
    return DONE;
  } else if (type == "Ping") {
    return CONTINUE;
  } else if (type == "JavaScriptIsAlive") {
    return CONTINUE;
  } else {
    return InternalError("Unknown message type: " + type);
  }
}

// NaCl browser tests serve files out of the build directory because nexes and
// pexes are artifacts of the build.  To keep things tidy, all test data is kept
// in a subdirectory.  Several variants of a test may be run, for example when
// linked against newlib and when linked against glibc.  These variants are kept
// in different subdirectories.  For example, the build directory will look
// something like this on Linux:
// out/
//     Release/
//             nacl_test_data/
//                            newlib/
//                            glibc/
//                            pnacl/
static bool GetNaClVariantRoot(const base::FilePath::StringType& variant,
                               base::FilePath* document_root) {
  if (!ui_test_utils::GetRelativeBuildDirectory(document_root))
    return false;
  *document_root = document_root->Append(FILE_PATH_LITERAL("nacl_test_data"));
  *document_root = document_root->Append(variant);
  return true;
}

static void AddPnaclParm(const base::FilePath::StringType& url,
                         base::FilePath::StringType* url_with_parm) {
  if (url.find(FILE_PATH_LITERAL("?")) == base::FilePath::StringType::npos) {
    *url_with_parm = url + FILE_PATH_LITERAL("?pnacl=1");
  } else {
    *url_with_parm = url + FILE_PATH_LITERAL("&pnacl=1");
  }
}

NaClBrowserTestBase::NaClBrowserTestBase() {
}

NaClBrowserTestBase::~NaClBrowserTestBase() {
}

void NaClBrowserTestBase::SetUpCommandLine(base::CommandLine* command_line) {
  command_line->AppendSwitch(switches::kEnableNaCl);
}

void NaClBrowserTestBase::SetUpOnMainThread() {
  ASSERT_TRUE(StartTestServer()) << "Cannot start test server.";
}

bool NaClBrowserTestBase::GetDocumentRoot(base::FilePath* document_root) {
  return GetNaClVariantRoot(Variant(), document_root);
}

bool NaClBrowserTestBase::IsAPnaclTest() {
  return false;
}

GURL NaClBrowserTestBase::TestURL(
    const base::FilePath::StringType& url_fragment) {
  base::FilePath expanded_url = base::FilePath(FILE_PATH_LITERAL("/"));
  expanded_url = expanded_url.Append(url_fragment);
  return test_server_->GetURL(expanded_url.MaybeAsASCII());
}

bool NaClBrowserTestBase::RunJavascriptTest(
    const GURL& url,
    content::TestMessageHandler* handler) {
  content::JavascriptTestObserver observer(
      browser()->tab_strip_model()->GetActiveWebContents(),
      handler);
  ui_test_utils::NavigateToURL(browser(), url);
  return observer.Run();
}

void NaClBrowserTestBase::RunLoadTest(
    const base::FilePath::StringType& test_file) {
  LoadTestMessageHandler handler;
  base::FilePath::StringType test_file_with_pnacl = test_file;
  if (IsAPnaclTest()) {
    AddPnaclParm(test_file, &test_file_with_pnacl);
  }
  base::FilePath::StringType test_file_with_both = test_file_with_pnacl;
  bool ok = RunJavascriptTest(TestURL(test_file_with_both), &handler);
  ASSERT_TRUE(ok) << handler.error_message();
  ASSERT_TRUE(handler.test_passed()) << "Test failed.";
}

void NaClBrowserTestBase::RunNaClIntegrationTest(
    const base::FilePath::StringType& url_fragment, bool full_url) {
  NaClIntegrationMessageHandler handler;
  base::FilePath::StringType url_fragment_with_pnacl = url_fragment;
  if (IsAPnaclTest()) {
    AddPnaclParm(url_fragment, &url_fragment_with_pnacl);
  }
  base::FilePath::StringType url_fragment_with_both = url_fragment_with_pnacl;
  bool ok = RunJavascriptTest(full_url
                              ? GURL(url_fragment_with_both)
                              : TestURL(url_fragment_with_both),
                              &handler);
  ASSERT_TRUE(ok) << handler.error_message();
  ASSERT_TRUE(handler.test_passed()) << "Test failed.";
}

bool NaClBrowserTestBase::StartTestServer() {
  // Launch the web server.
  base::FilePath document_root;
  if (!GetDocumentRoot(&document_root))
    return false;
  test_server_.reset(new net::EmbeddedTestServer);
  test_server_->ServeFilesFromSourceDirectory(document_root);
  return test_server_->Start();
}

base::FilePath::StringType NaClBrowserTestNewlib::Variant() {
  return FILE_PATH_LITERAL("newlib");
}

base::FilePath::StringType NaClBrowserTestGLibc::Variant() {
  return FILE_PATH_LITERAL("glibc");
}

base::FilePath::StringType NaClBrowserTestPnacl::Variant() {
  return FILE_PATH_LITERAL("pnacl");
}

bool NaClBrowserTestPnacl::IsAPnaclTest() {
  return true;
}

void NaClBrowserTestPnaclSubzero::SetUpCommandLine(
    base::CommandLine* command_line) {
  NaClBrowserTestPnacl::SetUpCommandLine(command_line);
  command_line->AppendSwitch(switches::kForcePNaClSubzero);
}

base::FilePath::StringType NaClBrowserTestNonSfiMode::Variant() {
  return FILE_PATH_LITERAL("libc-free");
}

void NaClBrowserTestNonSfiMode::SetUpCommandLine(
    base::CommandLine* command_line) {
  NaClBrowserTestBase::SetUpCommandLine(command_line);
  command_line->AppendSwitch(switches::kEnableNaClNonSfiMode);
}

base::FilePath::StringType NaClBrowserTestStatic::Variant() {
  return FILE_PATH_LITERAL("static");
}

bool NaClBrowserTestStatic::GetDocumentRoot(base::FilePath* document_root) {
  *document_root = base::FilePath(FILE_PATH_LITERAL("chrome/test/data/nacl"));
  return true;
}

base::FilePath::StringType NaClBrowserTestPnaclNonSfi::Variant() {
  return FILE_PATH_LITERAL("nonsfi");
}

void NaClBrowserTestPnaclNonSfi::SetUpCommandLine(
    base::CommandLine* command_line) {
  NaClBrowserTestBase::SetUpCommandLine(command_line);
  command_line->AppendSwitch(switches::kEnableNaClNonSfiMode);
}

void NaClBrowserTestNewlibExtension::SetUpCommandLine(
    base::CommandLine* command_line) {
  NaClBrowserTestBase::SetUpCommandLine(command_line);
  base::FilePath src_root;
  ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_root));

  // Extension-based tests should specialize the GetDocumentRoot() / Variant()
  // to point at the isolated the test extension directory.
  // Otherwise, multiple NaCl extensions tests will end up sharing the
  // same directory when loading the extension files.
  base::FilePath document_root;
  ASSERT_TRUE(GetDocumentRoot(&document_root));

  // Document root is relative to source root, and source root may not be CWD.
  command_line->AppendSwitchPath(extensions::switches::kLoadExtension,
                                 src_root.Append(document_root));
}

void NaClBrowserTestGLibcExtension::SetUpCommandLine(
    base::CommandLine* command_line) {
  NaClBrowserTestBase::SetUpCommandLine(command_line);
  base::FilePath src_root;
  ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_root));

  // Extension-based tests should specialize the GetDocumentRoot() / Variant()
  // to point at the isolated the test extension directory.
  // Otherwise, multiple NaCl extensions tests will end up sharing the
  // same directory when loading the extension files.
  base::FilePath document_root;
  ASSERT_TRUE(GetDocumentRoot(&document_root));

  // Document root is relative to source root, and source root may not be CWD.
  command_line->AppendSwitchPath(extensions::switches::kLoadExtension,
                                 src_root.Append(document_root));
}
