// Copyright 2013 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 "base/bind.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/chromeos/first_run/drive_first_run_controller.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_notification_observer.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_system.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"

namespace chromeos {

namespace {

// Directory containing data files for the tests.
const char kTestDirectory[] = "drive_first_run";

// Directory containing correct hosted app page served by the test server.
const char kGoodServerDirectory[] = "good";

// Directory containing incorrect hosted app page served by the test server.
const char kBadServerDirectory[] = "bad";

// Name of the test hosted app .crx file.
const char kTestAppCrxName[] = "app.crx";

// App id of the test hosted app.
const char kTestAppId[] = "kipccbklifbfblhpplnmklieangbjnhb";

// The endpoint belonging to the test hosted app.
const char kTestEndpointUrl[] = "http://example.com/endpoint.html";

}  // namespace

class DriveFirstRunTest : public InProcessBrowserTest,
                          public DriveFirstRunController::Observer {
 protected:
  DriveFirstRunTest();

  // InProcessBrowserTest overrides:
  void SetUpOnMainThread() override;
  void TearDownOnMainThread() override;

  // DriveFirstRunController::Observer overrides:
  void OnCompletion(bool success) override;
  void OnTimedOut() override;

  void InstallApp();

  void InitTestServer(const std::string& directory);

  bool WaitForFirstRunResult();

  void EnableOfflineMode();

  void SetDelays(int initial_delay_secs, int timeout_secs);

  bool timed_out() const { return timed_out_; }

 private:
  // |controller_| is responsible for its own lifetime.
  DriveFirstRunController* controller_;
  scoped_refptr<content::MessageLoopRunner> runner_;

  bool timed_out_;
  bool waiting_for_result_;
  bool success_;
  base::FilePath test_data_dir_;
  std::string endpoint_url_;
};

DriveFirstRunTest::DriveFirstRunTest() :
    timed_out_(false),
    waiting_for_result_(false),
    success_(false) {}

void DriveFirstRunTest::SetUpOnMainThread() {
  InProcessBrowserTest::SetUpOnMainThread();
  PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
  test_data_dir_ = test_data_dir_.AppendASCII(kTestDirectory);

  host_resolver()->AddRule("example.com", "127.0.0.1");

  // |controller_| will delete itself when it completes.
  controller_ = new DriveFirstRunController(browser()->profile());
  controller_->AddObserver(this);
  controller_->SetDelaysForTest(0, 10);
  controller_->SetAppInfoForTest(kTestAppId, kTestEndpointUrl);
}

void DriveFirstRunTest::TearDownOnMainThread() {
  content::RunAllPendingInMessageLoop();
}

void DriveFirstRunTest::InitTestServer(const std::string& directory) {
  embedded_test_server()->ServeFilesFromDirectory(
      test_data_dir_.AppendASCII(directory));
  ASSERT_TRUE(embedded_test_server()->Start());

  // Configure the endpoint to use the test server's port.
  const GURL url(kTestEndpointUrl);
  GURL::Replacements replacements;
  std::string port(base::IntToString(embedded_test_server()->port()));
  replacements.SetPortStr(port);
  endpoint_url_ = url.ReplaceComponents(replacements).spec();
  controller_->SetAppInfoForTest(kTestAppId, endpoint_url_);
}

void DriveFirstRunTest::InstallApp() {
  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
      browser()->profile())->extension_service();
  scoped_refptr<extensions::CrxInstaller> installer =
      extensions::CrxInstaller::CreateSilent(extension_service);

  installer->InstallCrx(test_data_dir_.AppendASCII(kTestAppCrxName));
  ExtensionTestNotificationObserver observer(browser());
  observer.WaitForExtensionLoad();

  ASSERT_TRUE(extension_service->GetExtensionById(kTestAppId, false));
}

void DriveFirstRunTest::EnableOfflineMode() {
  controller_->EnableOfflineMode();
}

void DriveFirstRunTest::SetDelays(int initial_delay_secs, int timeout_secs) {
  controller_->SetDelaysForTest(initial_delay_secs, timeout_secs);
}

bool DriveFirstRunTest::WaitForFirstRunResult() {
  waiting_for_result_ = true;
  runner_ = new content::MessageLoopRunner;
  runner_->Run();
  EXPECT_FALSE(waiting_for_result_);
  return success_;
}

void DriveFirstRunTest::OnCompletion(bool success) {
  EXPECT_TRUE(waiting_for_result_);
  waiting_for_result_ = false;
  success_ = success;
  runner_->Quit();

  // |controller_| will eventually delete itself upon completion, so invalidate
  // the pointer.
  controller_ = NULL;
}

void DriveFirstRunTest::OnTimedOut() {
  timed_out_ = true;
}

IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, OfflineEnabled) {
  InstallApp();
  InitTestServer(kGoodServerDirectory);
  EnableOfflineMode();
  EXPECT_TRUE(WaitForFirstRunResult());
}

IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, AppNotInstalled) {
  InitTestServer(kGoodServerDirectory);
  EnableOfflineMode();
  EXPECT_FALSE(WaitForFirstRunResult());
  EXPECT_FALSE(timed_out());
}

IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, TimedOut) {
  // Test that the controller times out instead of hanging forever.
  InstallApp();
  InitTestServer(kBadServerDirectory);
  SetDelays(0, 0);
  EnableOfflineMode();
  EXPECT_FALSE(WaitForFirstRunResult());
  EXPECT_TRUE(timed_out());
}

}  // namespace chromeos
