// Copyright 2019 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 "content/browser/background_sync/background_sync_base_browsertest.h"

#include <memory>
#include <set>
#include <vector>
#include "base/metrics/field_trial_param_associator.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "content/browser/background_sync/background_sync_manager.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/test/background_sync_test_util.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/mock_background_sync_controller.h"

namespace content {

BackgroundSyncBaseBrowserTest::BackgroundSyncBaseBrowserTest() {}
BackgroundSyncBaseBrowserTest::~BackgroundSyncBaseBrowserTest() {}

std::string BackgroundSyncBaseBrowserTest::BuildScriptString(
    const std::string& function,
    const std::string& argument) {
  return base::StringPrintf("%s('%s');", function.c_str(), argument.c_str());
}

std::string BackgroundSyncBaseBrowserTest::BuildExpectedResult(
    const std::string& tag,
    const std::string& action) {
  return base::StringPrintf("%s%s %s", kSuccessfulOperationPrefix, tag.c_str(),
                            action.c_str());
}

bool BackgroundSyncBaseBrowserTest::RegistrationPending(
    const std::string& tag) {
  bool is_pending;
  base::RunLoop run_loop;

  StoragePartitionImpl* storage = GetStorage();
  BackgroundSyncContextImpl* sync_context = storage->GetBackgroundSyncContext();
  ServiceWorkerContextWrapper* service_worker_context =
      static_cast<ServiceWorkerContextWrapper*>(
          storage->GetServiceWorkerContext());

  auto callback = base::BindOnce(
      &BackgroundSyncBaseBrowserTest::RegistrationPendingCallback,
      base::Unretained(this), run_loop.QuitClosure(),
      base::ThreadTaskRunnerHandle::Get(), &is_pending);

  RunOrPostTaskOnThread(
      FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
      base::BindOnce(
          &BackgroundSyncBaseBrowserTest::RegistrationPendingOnCoreThread,
          base::Unretained(this), base::WrapRefCounted(sync_context),
          base::WrapRefCounted(service_worker_context), tag,
          https_server_->GetURL(kDefaultTestURL), std::move(callback)));

  run_loop.Run();

  return is_pending;
}

bool BackgroundSyncBaseBrowserTest::CompleteDelayedSyncEvent() {
  std::string script_result;
  EXPECT_TRUE(RunScript("completeDelayedSyncEvent()", &script_result));
  return script_result == BuildExpectedResult("delay", "completing");
}

void BackgroundSyncBaseBrowserTest::RegistrationPendingCallback(
    base::OnceClosure quit,
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    bool* result_out,
    bool result) {
  *result_out = result;
  task_runner->PostTask(FROM_HERE, std::move(quit));
}

void BackgroundSyncBaseBrowserTest::RegistrationPendingDidGetSyncRegistration(
    const std::string& tag,
    base::OnceCallback<void(bool)> callback,
    BackgroundSyncStatus error_type,
    std::vector<std::unique_ptr<BackgroundSyncRegistration>> registrations) {
  ASSERT_EQ(BACKGROUND_SYNC_STATUS_OK, error_type);
  // Find the right registration in the list and check its status.
  for (const auto& registration : registrations) {
    if (registration->options()->tag == tag) {
      std::move(callback).Run(registration->sync_state() ==
                              blink::mojom::BackgroundSyncState::PENDING);
      return;
    }
  }
  ADD_FAILURE() << "Registration should exist";
}

void BackgroundSyncBaseBrowserTest::RegistrationPendingDidGetSWRegistration(
    const scoped_refptr<BackgroundSyncContextImpl> sync_context,
    const std::string& tag,
    base::OnceCallback<void(bool)> callback,
    blink::ServiceWorkerStatusCode status,
    scoped_refptr<ServiceWorkerRegistration> registration) {
  ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
  int64_t service_worker_id = registration->id();
  BackgroundSyncManager* sync_manager = sync_context->background_sync_manager();
  sync_manager->GetOneShotSyncRegistrations(
      service_worker_id,
      base::BindOnce(&BackgroundSyncBaseBrowserTest::
                         RegistrationPendingDidGetSyncRegistration,
                     base::Unretained(this), tag, std::move(callback)));
}

void BackgroundSyncBaseBrowserTest::RegistrationPendingOnCoreThread(
    const scoped_refptr<BackgroundSyncContextImpl> sync_context,
    const scoped_refptr<ServiceWorkerContextWrapper> sw_context,
    const std::string& tag,
    const GURL& url,
    base::OnceCallback<void(bool)> callback) {
  sw_context->FindReadyRegistrationForClientUrl(
      url, base::BindOnce(&BackgroundSyncBaseBrowserTest::
                              RegistrationPendingDidGetSWRegistration,
                          base::Unretained(this), sync_context, tag,
                          std::move(callback)));
}

void BackgroundSyncBaseBrowserTest::SetTestClockOnCoreThread(
    BackgroundSyncContextImpl* sync_context,
    base::SimpleTestClock* clock) {
  DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
  DCHECK(clock);

  BackgroundSyncManager* background_sync_manager =
      sync_context->background_sync_manager();
  background_sync_manager->set_clock(clock);
}

void BackgroundSyncBaseBrowserTest::SetUp() {
  const char kTrialName[] = "BackgroundSync";
  const char kGroupName[] = "BackgroundSync";
  const char kFeatureName[] = "PeriodicBackgroundSync";
  scoped_refptr<base::FieldTrial> trial =
      base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
  std::map<std::string, std::string> params;
  params["max_sync_attempts"] = "1";
  params["min_periodic_sync_events_interval_sec"] = "5";
  base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
      kTrialName, kGroupName, params);
  std::unique_ptr<base::FeatureList> feature_list(
      std::make_unique<base::FeatureList>());
  feature_list->RegisterFieldTrialOverride(
      kFeatureName, base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
  scoped_feature_list_.InitWithFeatureList(std::move(feature_list));

  background_sync_test_util::SetIgnoreNetworkChanges(true);
  ContentBrowserTest::SetUp();
}

void BackgroundSyncBaseBrowserTest::SetIncognitoMode(bool incognito) {
  shell_ = incognito ? CreateOffTheRecordBrowser() : shell();
  // Let any async shell creation logic finish.
  base::RunLoop().RunUntilIdle();
}

StoragePartitionImpl* BackgroundSyncBaseBrowserTest::GetStorage() {
  WebContents* web_contents = shell_->web_contents();
  return static_cast<StoragePartitionImpl*>(BrowserContext::GetStoragePartition(
      web_contents->GetBrowserContext(), web_contents->GetSiteInstance()));
}

WebContents* BackgroundSyncBaseBrowserTest::web_contents() {
  return shell_->web_contents();
}

void BackgroundSyncBaseBrowserTest::SetUpOnMainThread() {
  https_server_ = std::make_unique<net::EmbeddedTestServer>(
      net::EmbeddedTestServer::TYPE_HTTPS);
  https_server_->ServeFilesFromSourceDirectory(GetTestDataFilePath());
  ASSERT_TRUE(https_server_->Start());

  SetIncognitoMode(false);
  background_sync_test_util::SetOnline(web_contents(), true);
  ASSERT_TRUE(LoadTestPage(kDefaultTestURL));

  ContentBrowserTest::SetUpOnMainThread();
}

void BackgroundSyncBaseBrowserTest::TearDownOnMainThread() {
  https_server_.reset();
}

bool BackgroundSyncBaseBrowserTest::LoadTestPage(const std::string& path) {
  return NavigateToURL(shell_, https_server_->GetURL(path));
}

bool BackgroundSyncBaseBrowserTest::RunScript(const std::string& script,
                                              std::string* result) {
  return content::ExecuteScriptAndExtractString(web_contents(), script, result);
}

void BackgroundSyncBaseBrowserTest::SetTestClock(base::SimpleTestClock* clock) {
  StoragePartitionImpl* storage = GetStorage();
  BackgroundSyncContextImpl* sync_context = storage->GetBackgroundSyncContext();

  // TODO(crbug.com/824858): Remove the else branch after the feature is
  // enabled. Also, try to make a RunOrPostTaskOnThreadAndReply() function so
  // the if/else isn't needed.
  if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
    SetTestClockOnCoreThread(sync_context, clock);
  } else {
    base::RunLoop run_loop;
    base::PostTaskAndReply(
        FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
        base::BindOnce(&BackgroundSyncBaseBrowserTest::SetTestClockOnCoreThread,
                       base::Unretained(this), base::Unretained(sync_context),
                       clock),
        run_loop.QuitClosure());
    run_loop.Run();
  }
}

void BackgroundSyncBaseBrowserTest::ClearStoragePartitionData() {
  // Clear data from the storage partition.  Parameters are set to clear data
  // for service workers, for all origins, for an unbounded time range.
  StoragePartitionImpl* storage = GetStorage();

  uint32_t storage_partition_mask =
      StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
  uint32_t quota_storage_mask =
      StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
  GURL delete_origin = GURL();
  const base::Time delete_begin = base::Time();
  base::Time delete_end = base::Time::Max();

  base::RunLoop run_loop;

  storage->ClearData(storage_partition_mask, quota_storage_mask, delete_origin,
                     delete_begin, delete_end, run_loop.QuitClosure());

  run_loop.Run();
}

std::string BackgroundSyncBaseBrowserTest::PopConsoleString() {
  std::string script_result;
  EXPECT_TRUE(RunScript("resultQueue.pop()", &script_result));
  return script_result;
}

bool BackgroundSyncBaseBrowserTest::PopConsole(
    const std::string& expected_msg) {
  std::string script_result = PopConsoleString();
  return script_result == expected_msg;
}

bool BackgroundSyncBaseBrowserTest::RegisterServiceWorker() {
  std::string script_result;
  EXPECT_TRUE(RunScript("registerServiceWorker()", &script_result));
  return script_result == BuildExpectedResult("service worker", "registered");
}

}  // namespace content
