// Copyright 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/macros.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/session_hierarchy_match_checker.h"
#include "chrome/browser/sync/test/integration/sessions_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/sync/test/integration/typed_urls_helper.h"
#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/url_constants.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/history/core/browser/history_types.h"
#include "components/sessions/core/session_types.h"
#include "components/sync/base/time.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/protocol/proto_value_conversions.h"
#include "components/sync/test/fake_server/sessions_hierarchy.h"
#include "ui/base/mojo/window_open_disposition.mojom.h"

using base::HistogramBase;
using base::HistogramSamples;
using base::HistogramTester;
using fake_server::SessionsHierarchy;
using sessions_helper::CheckInitialState;
using sessions_helper::GetLocalWindows;
using sessions_helper::GetSessionData;
using sessions_helper::SessionsSyncManagerHasTabWithURL;
using sessions_helper::MoveTab;
using sessions_helper::NavigateTab;
using sessions_helper::NavigateTabBack;
using sessions_helper::NavigateTabForward;
using sessions_helper::OpenTab;
using sessions_helper::OpenTabAtIndex;
using sessions_helper::OpenTabFromSourceIndex;
using sessions_helper::ScopedWindowMap;
using sessions_helper::SessionWindowMap;
using sessions_helper::SyncedSessionVector;
using sessions_helper::WindowsMatch;
using typed_urls_helper::GetUrlFromClient;

namespace {

static const char* kURL1 = "data:text/html,<html><title>Test</title></html>";
static const char* kURL2 = "data:text/html,<html><title>Test2</title></html>";
static const char* kURL3 = "data:text/html,<html><title>Test3</title></html>";
static const char* kBaseFragmentURL =
    "data:text/html,<html><title>Fragment</title><body></body></html>";
static const char* kSpecifiedFragmentURL =
    "data:text/html,<html><title>Fragment</title><body></body></html>#fragment";

void ExpectUniqueSampleGE(const HistogramTester& histogram_tester,
                          const std::string& name,
                          HistogramBase::Sample sample,
                          HistogramBase::Count expected_inclusive_lower_bound) {
  std::unique_ptr<HistogramSamples> samples =
      histogram_tester.GetHistogramSamplesSinceCreation(name);
  int sample_count = samples->GetCount(sample);
  EXPECT_GE(sample_count, expected_inclusive_lower_bound);
  EXPECT_EQ(sample_count, samples->TotalCount());
}

}  // namespace

class SingleClientSessionsSyncTest : public SyncTest {
 public:
  SingleClientSessionsSyncTest() : SyncTest(SINGLE_CLIENT) {}
  ~SingleClientSessionsSyncTest() override {}

  void ExpectNavigationChain(const std::vector<GURL>& urls) {
    ScopedWindowMap windows;
    ASSERT_TRUE(GetLocalWindows(0, &windows));
    ASSERT_EQ(windows.begin()->second->wrapped_window.tabs.size(), 1u);
    sessions::SessionTab* tab =
        windows.begin()->second->wrapped_window.tabs[0].get();

    int index = 0;
    EXPECT_EQ(urls.size(), tab->navigations.size());
    for (auto it = tab->navigations.begin(); it != tab->navigations.end();
         ++it, ++index) {
      EXPECT_EQ(urls[index], it->virtual_url());
    }
  }

  // Block until the expected hierarchy is recorded on the FakeServer for
  // profile 0. This will time out if the hierarchy is never
  // recorded.
  void WaitForHierarchyOnServer(
      const fake_server::SessionsHierarchy& hierarchy) {
    SessionHierarchyMatchChecker checker(hierarchy, GetSyncService(0),
                                         GetFakeServer());
    EXPECT_TRUE(checker.Wait());
  }

  // Shortcut to call WaitForHierarchyOnServer for only |url| in a single
  // window.
  void WaitForURLOnServer(const GURL& url) {
    WaitForHierarchyOnServer({{url.spec()}});
  }

  // Simulates receiving list of accounts in the cookie jar from ListAccounts
  // endpoint. Adds |account_ids| into signed in accounts, notifies
  // ProfileSyncService and waits for change to propagate to sync engine.
  void UpdateCookieJarAccountsAndWait(std::vector<std::string> account_ids,
                                      bool expected_cookie_jar_mismatch) {
    std::vector<gaia::ListedAccount> accounts;
    for (const auto& account_id : account_ids) {
      gaia::ListedAccount signed_in_account;
      signed_in_account.id = account_id;
      accounts.push_back(signed_in_account);
    }
    base::RunLoop run_loop;
    EXPECT_EQ(expected_cookie_jar_mismatch,
              GetClient(0)->service()->HasCookieJarMismatch(accounts));
    GetClient(0)->service()->OnGaiaAccountsInCookieUpdatedWithCallback(
        accounts, run_loop.QuitClosure());
    run_loop.Run();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(SingleClientSessionsSyncTest);
};

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, Sanity) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  ASSERT_TRUE(CheckInitialState(0));

  // Add a new session to client 0 and wait for it to sync.
  ScopedWindowMap old_windows;
  GURL url = GURL(kURL1);
  ASSERT_TRUE(OpenTab(0, url));
  ASSERT_TRUE(GetLocalWindows(0, &old_windows));
  ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());

  // Get foreign session data from client 0.
  SyncedSessionVector sessions;
  ASSERT_FALSE(GetSessionData(0, &sessions));
  ASSERT_EQ(0U, sessions.size());

  // Verify client didn't change.
  ScopedWindowMap new_windows;
  ASSERT_TRUE(GetLocalWindows(0, &new_windows));
  ASSERT_TRUE(WindowsMatch(old_windows, new_windows));

  WaitForURLOnServer(url);
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, NoSessions) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  WaitForHierarchyOnServer(SessionsHierarchy());
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, ChromeHistory) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  ASSERT_TRUE(CheckInitialState(0));

  ASSERT_TRUE(OpenTab(0, GURL(chrome::kChromeUIHistoryURL)));
  WaitForURLOnServer(GURL(chrome::kChromeUIHistoryURL));
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, TimestampMatchesHistory) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  ASSERT_TRUE(CheckInitialState(0));

  const GURL url(kURL1);

  ScopedWindowMap windows;
  ASSERT_TRUE(OpenTab(0, url));
  ASSERT_TRUE(GetLocalWindows(0, &windows));

  int found_navigations = 0;
  for (auto it = windows.begin(); it != windows.end(); ++it) {
    for (auto it2 = it->second->wrapped_window.tabs.begin();
         it2 != it->second->wrapped_window.tabs.end(); ++it2) {
      for (auto it3 = (*it2)->navigations.begin();
           it3 != (*it2)->navigations.end(); ++it3) {
        const base::Time timestamp = it3->timestamp();

        history::URLRow virtual_row;
        ASSERT_TRUE(GetUrlFromClient(0, it3->virtual_url(), &virtual_row));
        const base::Time history_timestamp = virtual_row.last_visit();

        ASSERT_EQ(timestamp, history_timestamp);
        ++found_navigations;
      }
    }
  }
  ASSERT_EQ(1, found_navigations);
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, ResponseCodeIsPreserved) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  ASSERT_TRUE(CheckInitialState(0));

  const GURL url(kURL1);
  ScopedWindowMap windows;
  ASSERT_TRUE(OpenTab(0, url));
  ASSERT_TRUE(GetLocalWindows(0, &windows));

  int found_navigations = 0;
  for (auto it = windows.begin(); it != windows.end(); ++it) {
    for (auto it2 = it->second->wrapped_window.tabs.begin();
         it2 != it->second->wrapped_window.tabs.end(); ++it2) {
      for (auto it3 = (*it2)->navigations.begin();
           it3 != (*it2)->navigations.end(); ++it3) {
        EXPECT_EQ(200, it3->http_status_code());
        ++found_navigations;
      }
    }
  }
  ASSERT_EQ(1, found_navigations);
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, FragmentURLNavigation) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  const GURL url(kBaseFragmentURL);
  ASSERT_TRUE(OpenTab(0, url));
  WaitForURLOnServer(url);

  const GURL fragment_url(kSpecifiedFragmentURL);
  NavigateTab(0, fragment_url);
  WaitForURLOnServer(fragment_url);
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest,
                       NavigationChainForwardBack) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  GURL first_url = GURL(kURL1);
  ASSERT_TRUE(OpenTab(0, first_url));
  WaitForURLOnServer(first_url);

  GURL second_url = GURL(kURL2);
  NavigateTab(0, second_url);
  WaitForURLOnServer(second_url);

  NavigateTabBack(0);
  WaitForURLOnServer(first_url);

  ExpectNavigationChain({first_url, second_url});

  NavigateTabForward(0);
  WaitForURLOnServer(second_url);

  ExpectNavigationChain({first_url, second_url});
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest,
                       NavigationChainAlteredDestructively) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  GURL base_url = GURL(kURL1);
  ASSERT_TRUE(OpenTab(0, base_url));
  WaitForURLOnServer(base_url);

  GURL first_url = GURL(kURL2);
  ASSERT_TRUE(NavigateTab(0, first_url));
  WaitForURLOnServer(first_url);

  // Check that the navigation chain matches the above sequence of {base_url,
  // first_url}.
  ExpectNavigationChain({base_url, first_url});

  NavigateTabBack(0);
  WaitForURLOnServer(base_url);

  GURL second_url = GURL(kURL3);
  NavigateTab(0, second_url);
  WaitForURLOnServer(second_url);

  NavigateTabBack(0);
  WaitForURLOnServer(base_url);

  // Check that the navigation chain contains second_url where first_url was
  // before.
  ExpectNavigationChain({base_url, second_url});
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, OpenNewTab) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  GURL base_url = GURL(kURL1);
  ASSERT_TRUE(OpenTabAtIndex(0, 0, base_url));

  WaitForURLOnServer(base_url);

  GURL new_tab_url = GURL(kURL2);
  ASSERT_TRUE(OpenTabAtIndex(0, 1, new_tab_url));

  WaitForHierarchyOnServer(
      SessionsHierarchy({{base_url.spec(), new_tab_url.spec()}}));
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, OpenNewWindow) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  GURL base_url = GURL(kURL1);
  ASSERT_TRUE(OpenTab(0, base_url));

  WaitForURLOnServer(base_url);

  GURL new_window_url = GURL(kURL2);
  AddBrowser(0);
  ASSERT_TRUE(OpenTab(1, new_window_url));

  WaitForHierarchyOnServer(
      SessionsHierarchy({{base_url.spec()}, {new_window_url.spec()}}));
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, TabMovedToOtherWindow) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  GURL base_url = GURL(kURL1);
  GURL moved_tab_url = GURL(kURL2);

  ASSERT_TRUE(OpenTab(0, base_url));
  ASSERT_TRUE(OpenTabAtIndex(0, 1, moved_tab_url));

  GURL new_window_url = GURL(kURL3);
  AddBrowser(0);
  ASSERT_TRUE(OpenTab(1, new_window_url));

  WaitForHierarchyOnServer(SessionsHierarchy(
      {{base_url.spec(), moved_tab_url.spec()}, {new_window_url.spec()}}));

  // Move tab 1 in browser 0 to browser 1.
  MoveTab(0, 1, 1);

  WaitForHierarchyOnServer(SessionsHierarchy(
      {{base_url.spec()}, {new_window_url.spec(), moved_tab_url.spec()}}));
}

IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, SourceTabIDSet) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(CheckInitialState(0));

  GURL base_url = GURL(kURL1);
  ASSERT_TRUE(OpenTab(0, base_url));

  WaitForURLOnServer(base_url);

  GURL new_tab_url = GURL(kURL2);
  ASSERT_TRUE(OpenTabFromSourceIndex(
      0, 0, new_tab_url, WindowOpenDisposition::NEW_FOREGROUND_TAB));
  WaitForHierarchyOnServer(
      SessionsHierarchy({{base_url.spec(), new_tab_url.spec()}}));

  content::WebContents* original_tab_contents =
      GetBrowser(0)->tab_strip_model()->GetWebContentsAt(0);
  content::WebContents* new_tab_contents =
      GetBrowser(0)->tab_strip_model()->GetWebContentsAt(1);

  SessionID::id_type source_tab_id =
      SessionTabHelper::IdForTab(original_tab_contents);
  sync_sessions::SyncSessionsRouterTabHelper* new_tab_helper =
      sync_sessions::SyncSessionsRouterTabHelper::FromWebContents(
          new_tab_contents);
  EXPECT_EQ(new_tab_helper->source_tab_id(), source_tab_id);
}

void DumpSessionsOnServer(fake_server::FakeServer* fake_server) {
  auto entities = fake_server->GetSyncEntitiesByModelType(syncer::SESSIONS);
  for (const auto& entity : entities) {
    DVLOG(0) << "Session entity:\n" << *syncer::SyncEntityToValue(entity, true);
  }
}

// TODO(pavely): This test is flaky. Report failures in
// https://crbug.com/789129.
IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest,
                       DISABLED_CookieJarMismatch) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  ASSERT_TRUE(CheckInitialState(0));

  sync_pb::ClientToServerMessage message;

  // Simulate empty list of accounts in the cookie jar. This will record cookie
  // jar mismatch.
  UpdateCookieJarAccountsAndWait({}, true);
  // The HistogramTester objects are scoped to allow more precise verification.
  {
    HistogramTester histogram_tester;

    // Add a new session to client 0 and wait for it to sync.
    GURL url = GURL(kURL1);
    ASSERT_TRUE(OpenTab(0, url));
    WaitForURLOnServer(url);

    ASSERT_TRUE(GetFakeServer()->GetLastCommitMessage(&message));
    ASSERT_TRUE(message.commit().config_params().cookie_jar_mismatch());

    // It is possible that multiple sync cycles occurred during the call to
    // OpenTab, which would cause multiple identical samples.
    ExpectUniqueSampleGE(histogram_tester, "Sync.CookieJarMatchOnNavigation",
                         false, 1);
    ExpectUniqueSampleGE(histogram_tester, "Sync.CookieJarEmptyOnMismatch",
                         true, 1);
  }

  // Log sessions entities on fake server to verify that the last known tab's
  // url is kURL1.
  DumpSessionsOnServer(GetFakeServer());

  // Trigger a cookie jar change (user signing in to content area).
  // Updating the cookie jar has to travel to the sync engine. It is possible
  // something is already running or scheduled to run on the sync thread. We
  // want to block here and not create the HistogramTester below until we know
  // the cookie jar stats have been updated.
  UpdateCookieJarAccountsAndWait(
      {GetClient(0)->service()->signin()->GetAuthenticatedAccountId()}, false);

  {
    HistogramTester histogram_tester;

    // Trigger a sync and wait for it.
    GURL url = GURL(kURL2);
    ASSERT_TRUE(NavigateTab(0, url));
    WaitForURLOnServer(url);

    // Verify the cookie jar mismatch bool is set to false.
    ASSERT_TRUE(GetFakeServer()->GetLastCommitMessage(&message));
    ASSERT_FALSE(message.commit().config_params().cookie_jar_mismatch());
    // Log last commit message to verify that commit message was triggered by
    // navigation to kURL2.
    DVLOG(0) << "Commit message:\n"
             << *syncer::ClientToServerMessageToValue(message, true);

    // Verify the histograms were recorded properly.
    ExpectUniqueSampleGE(histogram_tester, "Sync.CookieJarMatchOnNavigation",
                         true, 1);
    histogram_tester.ExpectTotalCount("Sync.CookieJarEmptyOnMismatch", 0);
  }
}
