// 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.
//
// This file provides reliablity tests which run for ChromeFrame.
//
// Usage:
// <reliability test exe> --list=file --startline=start --endline=end [...]
// Upon invocation, it visits each of the URLs on line numbers between start
// and end, inclusive, stored in the input file. The line number starts from 1.
//
// Optional Switches:
// --iterations=num: goes through the list of URLs constructed in usage 2 or 3
//                   num times.
// --memoryusage: prints out memory usage when visiting each page.
// --logfile=filepath: saves the visit log to the specified path.
// --timeout=seconds: time out as specified in seconds during each
//                    page load.
// --nopagedown: won't simulate page down key presses after page load.
// --noclearprofile: do not clear profile dir before firing up each time.
// --savedebuglog: save Chrome, V8, and test debug log for each page loaded.
#include <fstream>
#include <ostream>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/file_version_info.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/i18n/time_formatting.h"
#include "base/path_service.h"
#include "base/prefs/json_pref_store.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/pref_value_store.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_file_util.h"
#include "base/time/time.h"
#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/common/automation_messages.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/net/url_fixer_upper.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome_frame/test/chrome_frame_test_utils.h"
#include "chrome_frame/test/ie_event_sink.h"
#include "chrome_frame/test/reliability/page_load_test.h"
#include "chrome_frame/utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "net/base/net_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::StrCaseEq;
using testing::StrCaseNe;

namespace {

// See comments at the beginning of the file for the definition of switches.
const char kListSwitch[] = "list";
const char kStartIndexSwitch[] = "startline";
const char kEndIndexSwitch[] = "endline";
const char kIterationSwitch[] = "iterations";
const char kContinuousLoadSwitch[] = "continuousload";
const char kMemoryUsageSwitch[] = "memoryusage";
const char kLogFileSwitch[] = "logfile";
const char kTimeoutSwitch[] = "timeout";
const char kNoPageDownSwitch[] = "nopagedown";
const char kNoClearProfileSwitch[] = "noclearprofile";
const char kSaveDebugLogSwitch[] = "savedebuglog";

// These are copied from v8 definitions as we cannot include them.
const char kV8LogFileSwitch[] = "logfile";
const char kV8LogFileDefaultName[] = "v8.log";

// String name of local chrome dll for looking up file information.
const wchar_t kChromeDll[] = L"chrome.dll";

base::FilePath g_url_file_path;
int32 g_start_index = 1;
int32 g_end_index = kint32max;
int32 g_iterations = 1;
bool g_memory_usage = false;
bool g_page_down = true;
bool g_clear_profile = true;
std::string g_end_url;
base::FilePath g_log_file_path;
bool g_save_debug_log = false;
base::FilePath g_chrome_log_path;
base::FilePath g_v8_log_path;
base::FilePath g_test_log_path;
bool g_stand_alone = false;

const int kUrlNavigationTimeoutSeconds = 20;
int g_timeout_seconds = kUrlNavigationTimeoutSeconds;

// Mocks document complete and load events.
class MockLoadListener : public chrome_frame_test::IEEventListener {
 public:
  MOCK_METHOD1(OnDocumentComplete, void (const wchar_t* url));  // NOLINT
  MOCK_METHOD1(OnLoad, void (const wchar_t* url));  // NOLINT
  MOCK_METHOD0(OnQuit, void ());  // NOLINT

 private:
  virtual void OnDocumentComplete(IDispatch* dispatch, VARIANT* url) {
    if (url->bstrVal)
      OnDocumentComplete(url->bstrVal);
  }
};

ACTION_P(QuitIE, event_sink) {
  EXPECT_HRESULT_SUCCEEDED(event_sink->CloseWebBrowser());
}

class PageLoadTest : public testing::Test {
 public:
  enum NavigationResult {
    NAVIGATION_ERROR = 0,
    NAVIGATION_SUCCESS,
  };

  typedef struct {
    // These are results from the test automation that drives Chrome
    NavigationResult result;
    int crash_dump_count;
    // These are stability metrics recorded by Chrome itself
    bool browser_clean_exit;
    int browser_launch_count;
    int page_load_count;
    int browser_crash_count;
    int renderer_crash_count;
    int plugin_crash_count;
  } NavigationMetrics;

  PageLoadTest() {}

  // Accept URL as std::string here because the url may also act as a test id
  // and needs to be logged in its original format even if invalid.
  void NavigateToURLLogResult(const std::string& url_string,
                              std::ofstream& log_file,
                              NavigationMetrics* metrics_output) {
    GURL url(url_string);
    NavigationMetrics metrics = {NAVIGATION_ERROR};
    std::ofstream test_log;

    // Create a test log.
    g_test_log_path = base::FilePath(FILE_PATH_LITERAL("test_log.log"));
    test_log.open(g_test_log_path.value().c_str());

    // Check file version info for chrome dll.
    scoped_ptr<FileVersionInfo> file_info;
#if defined(OS_WIN)
    file_info.reset(
        FileVersionInfo::CreateFileVersionInfo(base::FilePath(kChromeDll)));
#elif defined(OS_LINUX) || defined(OS_MACOSX)
    // TODO(fmeawad): the version retrieved here belongs to the test module and
    // not the chrome binary, need to be changed to chrome binary instead.
    file_info.reset(FileVersionInfo::CreateFileVersionInfoForCurrentModule());
#endif  // !defined(OS_WIN)
    std::wstring last_change = file_info->last_change();
    test_log << "Last Change: ";
    test_log << last_change << std::endl;


    // Log timestamp for test start.
    base::Time time_now = base::Time::Now();
    double time_start = time_now.ToDoubleT();
    test_log << "Test Start: ";
    test_log << base::TimeFormatFriendlyDateAndTime(time_now) << std::endl;

    HRESULT hr = E_FAIL;

    chrome_frame_test::TimedMsgLoop message_loop;

    // Launch IE.
    base::win::ScopedComPtr<IWebBrowser2> web_browser2;
    hr = chrome_frame_test::LaunchIEAsComServer(web_browser2.Receive());
    EXPECT_HRESULT_SUCCEEDED(hr);
    EXPECT_TRUE(web_browser2.get() != NULL);
    web_browser2->put_Visible(VARIANT_TRUE);

    // Log Browser Launched time.
    time_now = base::Time::Now();
    test_log << "browser_launched_seconds=";
    test_log << (time_now.ToDoubleT() - time_start) << std::endl;

    bool is_chrome_frame_navigation =
        StartsWith(UTF8ToWide(url.spec()), kChromeProtocolPrefix, true);

    CComObjectStack<chrome_frame_test::IEEventSink> ie_event_sink;
    MockLoadListener load_listener;
    // Disregard any interstitial about:blank loads.
    EXPECT_CALL(load_listener, OnDocumentComplete(StrCaseEq(L"about:blank")))
        .Times(testing::AnyNumber());

    // Note that we can't compare the loaded url directly with the given url
    // because the page may have redirected us to a different page, e.g.
    // www.google.com -> www.google.ca.
    if (is_chrome_frame_navigation) {
      EXPECT_CALL(load_listener, OnDocumentComplete(testing::_));
      EXPECT_CALL(load_listener, OnLoad(testing::_))
          .WillOnce(QuitIE(&ie_event_sink));
    } else {
      EXPECT_CALL(load_listener, OnDocumentComplete(StrCaseNe(L"about:blank")))
          .WillOnce(QuitIE(&ie_event_sink));
    }
    EXPECT_CALL(load_listener, OnQuit()).WillOnce(QUIT_LOOP(message_loop));

    // Attach the sink and navigate.
    ie_event_sink.set_listener(&load_listener);
    ie_event_sink.Attach(web_browser2);
    hr = ie_event_sink.Navigate(UTF8ToWide(url.spec()));
    if (SUCCEEDED(hr)) {
      message_loop.RunFor(base::TimeDelta::FromSeconds(g_timeout_seconds));
      if (!message_loop.WasTimedOut())
        metrics.result = NAVIGATION_SUCCESS;
    }

    // Log navigate complete time.
    time_now = base::Time::Now();
    test_log << "navigate_complete_seconds=";
    test_log << (time_now.ToDoubleT() - time_start) << std::endl;

    // Close IE.
    ie_event_sink.set_listener(NULL);
    ie_event_sink.Uninitialize();
    chrome_frame_test::CloseAllIEWindows();

    // Log end of test time.
    time_now = base::Time::Now();
    test_log << "total_duration_seconds=";
    test_log << (time_now.ToDoubleT() - time_start) << std::endl;

    // Get navigation result and metrics, and optionally write to the log file
    // provided.  The log format is:
    // <url> <navigation_result> <browser_crash_count> <renderer_crash_count>
    // <plugin_crash_count> <crash_dump_count> [chrome_log=<path>
    // v8_log=<path>] crash_dump=<path>
    if (log_file.is_open()) {
      log_file << url_string;
      switch (metrics.result) {
        case NAVIGATION_ERROR:
          log_file << " error";
          break;
        case NAVIGATION_SUCCESS:
          log_file << " success";
          break;
        default:
          break;
      }
    }

    // Get stability metrics recorded by Chrome itself.
    if (is_chrome_frame_navigation) {
      GetStabilityMetrics(&metrics);
    }

    if (log_file.is_open()) {
      log_file << " " << metrics.browser_crash_count \
               // The renderer crash count is flaky due to 1183283.
               // Ignore the count since we also catch crash by
               // crash_dump_count.
               << " " << 0 \
               << " " << metrics.plugin_crash_count \
               << " " << metrics.crash_dump_count;
    }

    // Close test log.
    test_log.close();

    if (log_file.is_open() && g_save_debug_log)
      SaveDebugLogs(log_file);

    // Log revision information for Chrome build under test.
    log_file << " " << "revision=" << last_change;

    // Get crash dumps.
    LogOrDeleteNewCrashDumps(log_file, &metrics);

    if (log_file.is_open()) {
      log_file << std::endl;
    }

    if (metrics_output) {
      *metrics_output = metrics;
    }
  }

  void NavigateThroughURLList(std::ofstream& log_file) {
    std::ifstream file(g_url_file_path.value().c_str());
    ASSERT_TRUE(file.is_open());

    // We navigate to URLs in the following order.
    // CF -> CF -> host -> CF -> CF -> host.
    for (int line_index = 1;
         line_index <= g_end_index && !file.eof();
         ++line_index) {
      std::string url_str;
      std::getline(file, url_str);

      if (file.fail()) {
        break;
      }

      // Every 3rd URL goes into the host browser.
      if (line_index % 3 != 0) {
        std::string actual_url;
        actual_url = WideToUTF8(kChromeProtocolPrefix);
        actual_url += url_str;
        url_str = actual_url;
      }

      if (g_start_index <= line_index) {
        NavigateToURLLogResult(url_str, log_file, NULL);
      }
    }

    file.close();
  }

 protected:
  virtual void SetUp() {
    // Initialize crash_dumps_dir_path_.
    PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dumps_dir_path_);
    base::FileEnumerator enumerator(crash_dumps_dir_path_,
                                    false,  // not recursive
                                    base::FileEnumerator::FILES);
    for (base::FilePath path = enumerator.Next(); !path.value().empty();
         path = enumerator.Next()) {
      if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")))
        crash_dumps_[path.BaseName()] = true;
    }

    if (g_clear_profile) {
      base::FilePath user_data_dir;
      chrome::GetChromeFrameUserDataDirectory(&user_data_dir);
      ASSERT_TRUE(file_util::DieFileDie(user_data_dir, true));
    }

    SetConfigBool(kChromeFrameHeadlessMode, true);
    SetConfigBool(kAllowUnsafeURLs, true);
  }

  virtual void TearDown() {
    DeleteConfigValue(kChromeFrameHeadlessMode);
    DeleteConfigValue(kAllowUnsafeURLs);
  }

  base::FilePath ConstructSavedDebugLogPath(const base::FilePath& debug_log_path,
                                            int index) {
    std::string suffix("_");
    suffix.append(base::IntToString(index));
    return debug_log_path.InsertBeforeExtensionASCII(suffix);
  }

  void SaveDebugLog(const base::FilePath& log_path, const std::wstring& log_id,
                    std::ofstream& log_file, int index) {
    if (!log_path.empty()) {
      base::FilePath saved_log_file_path =
          ConstructSavedDebugLogPath(log_path, index);
      if (base::Move(log_path, saved_log_file_path)) {
        log_file << " " << log_id << "=" << saved_log_file_path.value();
      }
    }
  }

  // Rename the chrome and v8 debug log files if existing, and save the file
  // paths in the log_file provided.
  void SaveDebugLogs(std::ofstream& log_file) {
    static int url_count = 1;
    SaveDebugLog(g_chrome_log_path, L"chrome_log", log_file, url_count);
    SaveDebugLog(g_v8_log_path, L"v8_log", log_file, url_count);
    SaveDebugLog(g_test_log_path, L"test_log", log_file, url_count);
    url_count++;
  }

  // If a log_file is provided, log the crash dump with the given path;
  // otherwise, delete the crash dump file.
  void LogOrDeleteCrashDump(std::ofstream& log_file,
                            base::FilePath crash_dump_file_name) {
    base::FilePath crash_dump_file_path(crash_dumps_dir_path_);
    crash_dump_file_path = crash_dump_file_path.Append(crash_dump_file_name);
    base::FilePath crash_text_file_path =
        crash_dump_file_path.ReplaceExtension(FILE_PATH_LITERAL("txt"));

    if (log_file.is_open()) {
      crash_dumps_[crash_dump_file_name] = true;
      log_file << " crash_dump=" << crash_dump_file_path.value().c_str();
    } else {
      ASSERT_TRUE(file_util::DieFileDie(
          crash_dump_file_path, false));
      ASSERT_TRUE(file_util::DieFileDie(
          crash_text_file_path, false));
    }
  }

  // Check whether there are new .dmp files. Additionally, write
  //     " crash_dump=<full path name of the .dmp file>"
  // to log_file.
  void LogOrDeleteNewCrashDumps(std::ofstream& log_file,
                                NavigationMetrics* metrics) {
    int num_dumps = 0;

    base::FileEnumerator enumerator(crash_dumps_dir_path_,
                                    false,  // not recursive
                                    base::FileEnumerator::FILES);
    for (base::FilePath path = enumerator.Next(); !path.value().empty();
         path = enumerator.Next()) {
      if (path.MatchesExtension(FILE_PATH_LITERAL(".dmp")) &&
          !crash_dumps_[path.BaseName()]) {
        LogOrDeleteCrashDump(log_file, path.BaseName());
        num_dumps++;
      }
    }
    if (metrics)
      metrics->crash_dump_count = num_dumps;
  }

  // Get a PrefService whose contents correspond to the Local State file
  // that was saved by the app as it closed.  The caller takes ownership of the
  // returned PrefService object.
  PrefService* GetLocalState(PrefRegistry* registry) {
    base::FilePath path;
    chrome::GetChromeFrameUserDataDirectory(&path);
    PrefServiceMockBuilder builder;
    builder.WithUserFilePrefs(
        path,
        JsonPrefStore::GetTaskRunnerForFile(
            path, content::BrowserThread::GetBlockingPool()));
    return builder.Create(registry);
  }

  void GetStabilityMetrics(NavigationMetrics* metrics) {
    if (!metrics)
      return;
    scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple();
    registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, false);
    registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, -1);
    registry->RegisterIntegerPref(prefs::kStabilityPageLoadCount, -1);
    registry->RegisterIntegerPref(prefs::kStabilityCrashCount, 0);
    registry->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);

    scoped_ptr<PrefService> local_state(GetLocalState(registry));
    if (!local_state.get())
      return;

    metrics->browser_clean_exit =
        local_state->GetBoolean(prefs::kStabilityExitedCleanly);
    metrics->browser_launch_count =
        local_state->GetInteger(prefs::kStabilityLaunchCount);
    metrics->page_load_count =
        local_state->GetInteger(prefs::kStabilityPageLoadCount);
    metrics->browser_crash_count =
        local_state->GetInteger(prefs::kStabilityCrashCount);
    metrics->renderer_crash_count =
        local_state->GetInteger(prefs::kStabilityRendererCrashCount);
    // TODO(huanr)
    metrics->plugin_crash_count = 0;

    if (!metrics->browser_clean_exit)
      metrics->browser_crash_count++;
  }

  base::FilePath GetSampleDataDir() {
    base::FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    test_dir = test_dir.AppendASCII("reliability");
    test_dir = test_dir.AppendASCII("sample_pages");
    return test_dir;
  }

  // The pathname of Chrome's crash dumps directory.
  base::FilePath crash_dumps_dir_path_;

  // The set of all the crash dumps we have seen.  Each crash generates a
  // .dmp and a .txt file in the crash dumps directory.  We only store the
  // .dmp files in this set.
  //
  // The set is implemented as a std::map.  The key is the file name, and
  // the value is false (the file is not in the set) or true (the file is
  // in the set).  The initial value for any key in std::map is 0 (false),
  // which in this case means a new file is not in the set initially,
  // exactly the semantics we want.
  std::map<base::FilePath, bool> crash_dumps_;
};

TEST_F(PageLoadTest, IEFullTabMode_Reliability) {
  std::ofstream log_file;

  if (!g_log_file_path.empty()) {
    log_file.open(g_log_file_path.value().c_str());
  }

  EXPECT_FALSE(g_url_file_path.empty());

  for (int k = 0; k < g_iterations; ++k) {
    NavigateThroughURLList(log_file);
  }

  log_file.close();
}

}  // namespace

namespace {
  void ReportHandler(const std::string& str) {
    // Ignore report events.
  }
}

void SetPageRange(const CommandLine& parsed_command_line) {
  // If calling into this function, we are running as a standalone program.
  g_stand_alone = true;

  // Since we use --enable-dcheck for reliability tests, suppress the error
  // dialog in the test process.
  logging::SetLogReportHandler(ReportHandler);

  if (parsed_command_line.HasSwitch(kStartIndexSwitch)) {
    ASSERT_TRUE(
        base::StringToInt(parsed_command_line.GetSwitchValueASCII(
                              kStartIndexSwitch),
                          &g_start_index));
    ASSERT_GT(g_start_index, 0);
  }

  if (parsed_command_line.HasSwitch(kEndIndexSwitch)) {
    ASSERT_TRUE(
        base::StringToInt(parsed_command_line.GetSwitchValueASCII(
                              kEndIndexSwitch),
                          &g_end_index));
    ASSERT_GT(g_end_index, 0);
  }

  ASSERT_TRUE(g_end_index >= g_start_index);

  if (parsed_command_line.HasSwitch(kListSwitch))
    g_url_file_path = parsed_command_line.GetSwitchValuePath(kListSwitch);

  if (parsed_command_line.HasSwitch(kIterationSwitch)) {
    ASSERT_TRUE(
        base::StringToInt(parsed_command_line.GetSwitchValueASCII(
                              kIterationSwitch),
                          &g_iterations));
    ASSERT_GT(g_iterations, 0);
  }

  if (parsed_command_line.HasSwitch(kMemoryUsageSwitch))
    g_memory_usage = true;

  if (parsed_command_line.HasSwitch(kLogFileSwitch))
    g_log_file_path = parsed_command_line.GetSwitchValuePath(kLogFileSwitch);

  if (parsed_command_line.HasSwitch(kTimeoutSwitch)) {
    ASSERT_TRUE(
        base::StringToInt(parsed_command_line.GetSwitchValueASCII(
                              kTimeoutSwitch),
                          &g_timeout_seconds));
    ASSERT_GT(g_timeout_seconds, 0);
  }

  if (parsed_command_line.HasSwitch(kNoPageDownSwitch))
    g_page_down = false;

  if (parsed_command_line.HasSwitch(kNoClearProfileSwitch))
    g_clear_profile = false;

  if (parsed_command_line.HasSwitch(kSaveDebugLogSwitch)) {
    g_save_debug_log = true;
    g_chrome_log_path = logging::GetLogFileName();
    // We won't get v8 log unless --no-sandbox is specified.
    if (parsed_command_line.HasSwitch(switches::kNoSandbox)) {
      PathService::Get(base::DIR_CURRENT, &g_v8_log_path);
      g_v8_log_path = g_v8_log_path.AppendASCII(kV8LogFileDefaultName);
      // The command line switch may override the default v8 log path.
      if (parsed_command_line.HasSwitch(switches::kJavaScriptFlags)) {
        CommandLine v8_command_line(
            parsed_command_line.GetSwitchValuePath(switches::kJavaScriptFlags));
        if (v8_command_line.HasSwitch(kV8LogFileSwitch)) {
          g_v8_log_path = base::MakeAbsoluteFilePath(
              v8_command_line.GetSwitchValuePath(kV8LogFileSwitch));
        }
      }
    }
  }
}
