// 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 "base/command_line.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_service.h"
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/download/download_test_file_activity_observer.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/download_item.h"
#include "content/public/common/page_transition_types.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/test/net/url_request_slow_download_job.h"

using content::BrowserContext;
using content::BrowserThread;
using content::DownloadItem;
using content::DownloadManager;
using content::URLRequestSlowDownloadJob;

class BrowserCloseTest : public InProcessBrowserTest {
 public:
  // Structure defining test cases for DownloadsCloseCheck.
  struct DownloadsCloseCheckCase {
    std::string DebugString() const;

    // Input
    struct {
      struct {
        int windows;
        int downloads;
      } regular;
      struct {
        int windows;
        int downloads;
      } incognito;
    } profile_a;

    struct {
      struct {
        int windows;
        int downloads;
      } regular;
      struct {
        int windows;
        int downloads;
      } incognito;
    } profile_b;

    // We always probe a window in profile A.
    enum { REGULAR = 0, INCOGNITO = 1 } window_to_probe;

    // Output
    Browser::DownloadClosePreventionType type;

    // Unchecked if type == DOWNLOAD_CLOSE_OK.
    int num_blocking;
  };

 protected:
  virtual void SetUpOnMainThread() OVERRIDE {
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
  }

  // Create a second profile to work within multi-profile.
  Profile* CreateSecondProfile() {
    base::FilePath user_data_dir;
    PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);

    if (!second_profile_data_dir_.CreateUniqueTempDirUnderPath(user_data_dir))
      return NULL;

    Profile* second_profile =
        g_browser_process->profile_manager()->GetProfile(
            second_profile_data_dir_.path());
    if (!second_profile)
      return NULL;

    bool result = second_profile_downloads_dir_.CreateUniqueTempDir();
    if (!result)
      return NULL;
    second_profile->GetPrefs()->SetFilePath(
        prefs::kDownloadDefaultDirectory,
        second_profile_downloads_dir_.path());

    return second_profile;
  }

  // Create |num_downloads| number of downloads that are stalled
  // (will quickly get to a place where the server won't
  // provide any more data) so that we can test closing the
  // browser with active downloads.
  void CreateStalledDownloads(Browser* browser, int num_downloads) {
    GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);

    if (num_downloads == 0)
      return;

    // Setup an observer waiting for the given number of downloads
    // to get to IN_PROGRESS.
    DownloadManager* download_manager =
        BrowserContext::GetDownloadManager(browser->profile());
    scoped_ptr<content::DownloadTestObserver> observer(
        new content::DownloadTestObserverInProgress(download_manager,
                                                    num_downloads));

    // Set of that number of downloads.
    size_t count_downloads = num_downloads;
    while (num_downloads--)
      ui_test_utils::NavigateToURLWithDisposition(
          browser, url, NEW_BACKGROUND_TAB,
          ui_test_utils::BROWSER_TEST_NONE);

    // Wait for them.
    observer->WaitForFinished();
    EXPECT_EQ(count_downloads,
              observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
  }

  // All all downloads created in CreateStalledDownloads() to
  // complete, and block in this routine until they do complete.
  void CompleteAllDownloads(Browser* browser) {
    GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
    ui_test_utils::NavigateToURL(browser, finish_url);

    // Go through and, for every single profile, wait until there are
    // no active downloads on that download manager.
    std::vector<Profile*> profiles(
        g_browser_process->profile_manager()->GetLoadedProfiles());
    for (std::vector<Profile*>::const_iterator pit = profiles.begin();
         pit != profiles.end(); ++pit) {
      DownloadService* download_service =
          DownloadServiceFactory::GetForBrowserContext(*pit);
      if (download_service->HasCreatedDownloadManager()) {
        DownloadManager *mgr = BrowserContext::GetDownloadManager(*pit);
        scoped_refptr<content::DownloadTestFlushObserver> observer(
            new content::DownloadTestFlushObserver(mgr));
        observer->WaitForFlush();
      }
      if ((*pit)->HasOffTheRecordProfile()) {
        DownloadService* incognito_download_service =
          DownloadServiceFactory::GetForBrowserContext(
              (*pit)->GetOffTheRecordProfile());
        if (incognito_download_service->HasCreatedDownloadManager()) {
          DownloadManager *mgr = BrowserContext::GetDownloadManager(
              (*pit)->GetOffTheRecordProfile());
          scoped_refptr<content::DownloadTestFlushObserver> observer(
              new content::DownloadTestFlushObserver(mgr));
          observer->WaitForFlush();
        }
      }
    }
  }

  // Create a Browser (with associated window) on the specified profile.
  Browser* CreateBrowserOnProfile(Profile* profile,
                                  chrome::HostDesktopType host_desktop_type) {
    Browser* new_browser =
        new Browser(Browser::CreateParams(profile, host_desktop_type));
    chrome::AddSelectedTabWithURL(new_browser, GURL(content::kAboutBlankURL),
                                  content::PAGE_TRANSITION_AUTO_TOPLEVEL);
    content::WaitForLoadStop(
        new_browser->tab_strip_model()->GetActiveWebContents());
    new_browser->window()->Show();
    return new_browser;
  }

  // Adjust the number of browsers and associated windows up or down
  // to |num_windows|.  This routine assumes that there is only a single
  // browser associated with the profile on entry.  |*base_browser| contains
  // this browser, and the profile is derived from that browser.  On output,
  // if |*base_browser| was destroyed (because |num_windows == 0|), NULL
  // is assigned to that memory location.
  bool AdjustBrowsersOnProfile(Browser** base_browser, int num_windows) {
    int num_downloads_blocking;
    if (num_windows == 0) {
      if (Browser::DOWNLOAD_CLOSE_OK !=
          (*base_browser)->OkToCloseWithInProgressDownloads(
              &num_downloads_blocking))
        return false;
      (*base_browser)->window()->Close();
      *base_browser = 0;
      return true;
    }

    // num_windows > 0
    Profile* profile((*base_browser)->profile());
    chrome::HostDesktopType host_desktop_type =
        (*base_browser)->host_desktop_type();
    for (int w = 1; w < num_windows; ++w) {
      CreateBrowserOnProfile(profile, host_desktop_type);
    }
    return true;
  }

  int TotalUnclosedBrowsers() {
    int count = 0;
    for (chrome::BrowserIterator it; !it.done(); it.Next()) {
      if (!it->IsAttemptingToCloseBrowser())
        count++;
    }
    return count;
  }

  // Note that this is invalid to call if TotalUnclosedBrowsers() == 0.
  Browser* FirstUnclosedBrowser() {
    for (chrome::BrowserIterator it; !it.done(); it.Next()) {
      if (!it->IsAttemptingToCloseBrowser())
        return *it;
    }
    return NULL;
  }

  bool SetupForDownloadCloseCheck() {
    first_profile_ = browser()->profile();

    bool result = first_profile_downloads_dir_.CreateUniqueTempDir();
    EXPECT_TRUE(result);
    if (!result) return false;
    first_profile_->GetPrefs()->SetFilePath(
        prefs::kDownloadDefaultDirectory,
        first_profile_downloads_dir_.path());

    second_profile_ = CreateSecondProfile();
    EXPECT_TRUE(second_profile_);
    if (!second_profile_) return false;

    DownloadTestFileActivityObserver(first_profile_) .EnableFileChooser(false);
    DownloadTestFileActivityObserver(second_profile_).EnableFileChooser(false);
    return true;
  }

  // Test a specific DownloadsCloseCheckCase.  Returns false if
  // an assertion has failed and the test should be aborted.
  bool ExecuteDownloadCloseCheckCase(size_t i) {
    const DownloadsCloseCheckCase& check_case(download_close_check_cases[i]);

    // Test invariant: so that we don't actually try and close the browser,
    // we always enter the function with a single browser window open on the
    // main profile.  That means we need to exit the function the same way.
    // So we setup everything except for the |first_profile_| regular, and then
    // flip the bit on the main window.
    // Note that this means that browser() is unreliable in the context
    // of this function or its callers; we'll be killing that main window
    // and recreating it fairly frequently.
    int unclosed_browsers = TotalUnclosedBrowsers();
    EXPECT_EQ(1, unclosed_browsers);
    if (1 != unclosed_browsers)
      return false;

    Browser* entry_browser = FirstUnclosedBrowser();
    EXPECT_EQ(first_profile_, entry_browser->profile())
        << "Case" << i
        << ": " << check_case.DebugString();
    if (first_profile_ != entry_browser->profile())
      return false;
    int total_download_count = DownloadService::DownloadCountAllProfiles();
    EXPECT_EQ(0, total_download_count)
        << "Case " << i
        << ": " << check_case.DebugString();
    if (0 != total_download_count)
      return false;

    Profile* first_profile_incognito = first_profile_->GetOffTheRecordProfile();
    Profile* second_profile_incognito =
        second_profile_->GetOffTheRecordProfile();
    DownloadTestFileActivityObserver(first_profile_incognito)
        .EnableFileChooser(false);
    DownloadTestFileActivityObserver(second_profile_incognito)
        .EnableFileChooser(false);

    // For simplicty of coding, we create a window on each profile so that
    // we can easily create downloads, then we destroy or create windows
    // as necessary.
    chrome::HostDesktopType host_desktop_type =
        entry_browser->host_desktop_type();
    Browser* browser_a_regular(CreateBrowserOnProfile(first_profile_,
                                                      host_desktop_type));
    Browser* browser_a_incognito(
        CreateBrowserOnProfile(first_profile_incognito, host_desktop_type));
    Browser* browser_b_regular(CreateBrowserOnProfile(second_profile_,
                                                      host_desktop_type));
    Browser* browser_b_incognito(
        CreateBrowserOnProfile(second_profile_incognito, host_desktop_type));

    // Kill our entry browser.
    entry_browser->window()->Close();
    entry_browser = NULL;

    // Create all downloads needed.
    CreateStalledDownloads(
        browser_a_regular, check_case.profile_a.regular.downloads);
    CreateStalledDownloads(
        browser_a_incognito, check_case.profile_a.incognito.downloads);
    CreateStalledDownloads(
        browser_b_regular, check_case.profile_b.regular.downloads);
    CreateStalledDownloads(
        browser_b_incognito, check_case.profile_b.incognito.downloads);

    // Adjust the windows
    Browser** browsers[] = {
      &browser_a_regular, &browser_a_incognito,
      &browser_b_regular, &browser_b_incognito
    };
    int window_counts[] = {
      check_case.profile_a.regular.windows,
      check_case.profile_a.incognito.windows,
      check_case.profile_b.regular.windows,
      check_case.profile_b.incognito.windows,
    };
    for (size_t j = 0; j < arraysize(browsers); ++j) {
      bool result = AdjustBrowsersOnProfile(browsers[j], window_counts[j]);
      EXPECT_TRUE(result);
      if (!result)
        return false;
    }
    content::RunAllPendingInMessageLoop();

    // All that work, for this one little test.
    EXPECT_TRUE((check_case.window_to_probe ==
                 DownloadsCloseCheckCase::REGULAR) ||
                (check_case.window_to_probe ==
                 DownloadsCloseCheckCase::INCOGNITO));
    if (!((check_case.window_to_probe ==
           DownloadsCloseCheckCase::REGULAR) ||
          (check_case.window_to_probe ==
           DownloadsCloseCheckCase::INCOGNITO)))
      return false;

    int num_downloads_blocking;
    Browser* browser_to_probe =
        (check_case.window_to_probe == DownloadsCloseCheckCase::REGULAR ?
         browser_a_regular :
         browser_a_incognito);
    Browser::DownloadClosePreventionType type =
        browser_to_probe->OkToCloseWithInProgressDownloads(
            &num_downloads_blocking);
    EXPECT_EQ(check_case.type, type) << "Case " << i
                                     << ": " << check_case.DebugString();
    if (type != Browser::DOWNLOAD_CLOSE_OK)
      EXPECT_EQ(check_case.num_blocking, num_downloads_blocking)
          << "Case " << i
          << ": " << check_case.DebugString();

    // Release all the downloads.
    CompleteAllDownloads(browser_to_probe);

    // Create a new main window and kill everything else.
    entry_browser = CreateBrowserOnProfile(first_profile_, host_desktop_type);
    for (chrome::BrowserIterator it; !it.done(); it.Next()) {
      if ((*it) != entry_browser) {
        if (!it->window()) {
          ADD_FAILURE();
          return false;
        }
        it->window()->Close();
      }
    }
    content::RunAllPendingInMessageLoop();

    return true;
  }

  static const DownloadsCloseCheckCase download_close_check_cases[];

  // DownloadCloseCheck variables.
  Profile* first_profile_;
  Profile* second_profile_;

  base::ScopedTempDir first_profile_downloads_dir_;
  base::ScopedTempDir second_profile_data_dir_;
  base::ScopedTempDir second_profile_downloads_dir_;
};

const BrowserCloseTest::DownloadsCloseCheckCase
BrowserCloseTest::download_close_check_cases[] = {
  // Top level nesting is {profile_a, profile_b}
  // Second level nesting is {regular, incognito
  // Third level (inner) nesting is {windows, downloads}

  // Last window (incognito) triggers browser close warning.
  {{{0, 0}, {1, 1}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO,
   Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 1},

  // Last incognito window triggers incognito close warning.
  {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO,
   Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE, 1},

  // Last incognito window with no downloads triggers no warning.
  {{{0, 0}, {1, 0}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO,
   Browser::DOWNLOAD_CLOSE_OK},

  // Last incognito window with window+download on another incognito profile
  // triggers no warning.
  {{{0, 0}, {1, 0}}, {{0, 0}, {1, 1}},
   BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO,
   Browser::DOWNLOAD_CLOSE_OK},

  // Non-last incognito window triggers no warning.
  {{{0, 0}, {2, 1}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO,
   Browser::DOWNLOAD_CLOSE_OK},

  // Non-last regular window triggers no warning.
  {{{2, 1}, {0, 0}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_OK},

  // Last regular window triggers browser close.
  {{{1, 1}, {0, 0}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 1},

  // Last regular window triggers browser close for download on different
  // profile.
  {{{1, 0}, {0, 0}}, {{0, 1}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 1},

  // Last regular window triggers no warning if incognito
  // active (http://crbug.com/61257).
  {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_OK},

  // Last regular window triggers no warning if other profile window active.
  {{{1, 1}, {0, 0}}, {{1, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_OK},

  // Last regular window triggers no warning if other incognito window
  // active.
  {{{1, 0}, {0, 0}}, {{0, 0}, {1, 1}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_OK},

  // Last regular window triggers no warning if incognito active.
  {{{1, 1}, {1, 0}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_OK},

  // Test plural for regular.
  {{{1, 2}, {0, 0}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::REGULAR,
   Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 2},

  // Test plural for incognito.
  {{{1, 0}, {1, 2}}, {{0, 0}, {0, 0}},
   BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO,
   Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE, 2},
};

std::string BrowserCloseTest::DownloadsCloseCheckCase::DebugString() const {
  std::string result;
  result += "{";
  if (profile_a.regular.windows || profile_a.regular.downloads)
    result += base::StringPrintf("Regular profile A: (%d w, %d d), ",
                                 profile_a.regular.windows,
                                 profile_a.regular.downloads);
  if (profile_a.incognito.windows || profile_a.incognito.downloads)
    result += base::StringPrintf("Incognito profile A: (%d w, %d d), ",
                                 profile_a.incognito.windows,
                                 profile_a.incognito.downloads);
  if (profile_b.regular.windows || profile_b.regular.downloads)
    result += base::StringPrintf("Regular profile B: (%d w, %d d), ",
                                 profile_b.regular.windows,
                                 profile_b.regular.downloads);
  if (profile_b.incognito.windows || profile_b.incognito.downloads)
    result += base::StringPrintf("Incognito profile B: (%d w, %d d), ",
                                 profile_b.incognito.windows,
                                 profile_b.incognito.downloads);
  result += (window_to_probe == REGULAR ? "Probe regular" :
             window_to_probe == INCOGNITO ? "Probe incognito" :
             "Probe unknown");
  result += "} -> ";
  if (type == Browser::DOWNLOAD_CLOSE_OK) {
    result += "No warning";
  } else {
    result += base::StringPrintf(
        "%s (%d downloads) warning",
        (type == Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN ? "Browser shutdown" :
         type == Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE ?
         "Incognito close" : "Unknown"),
        num_blocking);
  }
  return result;
}

// The following test is split into six chunks to reduce the chance
// of hitting the 25s timeout.

// This test is timing out very often under AddressSanitizer.
// http://crbug.com/111914 and http://crbug.com/103371.
// Crashing on Linux. http://crbug.com/100566
// Timing out on XP debug. http://crbug.com/111914
// Timing out, http://crbug.com/159449 .

#define MAYBE_DownloadsCloseCheck_0 DISABLED_DownloadsCloseCheck_0
#define MAYBE_DownloadsCloseCheck_1 DISABLED_DownloadsCloseCheck_1
#define MAYBE_DownloadsCloseCheck_2 DISABLED_DownloadsCloseCheck_2
#define MAYBE_DownloadsCloseCheck_3 DISABLED_DownloadsCloseCheck_3
#define MAYBE_DownloadsCloseCheck_4 DISABLED_DownloadsCloseCheck_4
#define MAYBE_DownloadsCloseCheck_5 DISABLED_DownloadsCloseCheck_5

IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_0) {
  ASSERT_TRUE(SetupForDownloadCloseCheck());
  for (size_t i = 0; i < arraysize(download_close_check_cases) / 6; ++i) {
    ExecuteDownloadCloseCheckCase(i);
  }
}

IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_1) {
  ASSERT_TRUE(SetupForDownloadCloseCheck());
  for (size_t i = arraysize(download_close_check_cases) / 6;
       i < 2 * arraysize(download_close_check_cases) / 6; ++i) {
    ExecuteDownloadCloseCheckCase(i);
  }
}

IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_2) {
  ASSERT_TRUE(SetupForDownloadCloseCheck());
  for (size_t i = 2 * arraysize(download_close_check_cases) / 6;
       i < 3 * arraysize(download_close_check_cases) / 6; ++i) {
    ExecuteDownloadCloseCheckCase(i);
  }
}

IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_3) {
  ASSERT_TRUE(SetupForDownloadCloseCheck());
  for (size_t i = 3 * arraysize(download_close_check_cases) / 6;
       i < 4 * arraysize(download_close_check_cases) / 6; ++i) {
    ExecuteDownloadCloseCheckCase(i);
  }
}

IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_4) {
  ASSERT_TRUE(SetupForDownloadCloseCheck());
  for (size_t i = 4 * arraysize(download_close_check_cases) / 6;
       i < 5 * arraysize(download_close_check_cases) / 6; ++i) {
    ExecuteDownloadCloseCheckCase(i);
  }
}

IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_5) {
  ASSERT_TRUE(SetupForDownloadCloseCheck());
  for (size_t i = 5 * arraysize(download_close_check_cases) / 6;
       i < 6 * arraysize(download_close_check_cases) / 6; ++i) {
    ExecuteDownloadCloseCheckCase(i);
  }
}
