// Copyright 2014 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 "components/feedback/feedback_uploader.h"

#include <memory>
#include <set>

#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/test/task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "components/feedback/feedback_report.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace feedback {

namespace {

constexpr char kReportOne[] = "one";
constexpr char kReportTwo[] = "two";
constexpr char kReportThree[] = "three";
constexpr char kReportFour[] = "four";
constexpr char kReportFive[] = "five";

constexpr base::TimeDelta kRetryDelayForTest =
    base::TimeDelta::FromMilliseconds(100);

class MockFeedbackUploader : public FeedbackUploader {
 public:
  MockFeedbackUploader(
      bool is_off_the_record,
      const base::FilePath& state_path,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
      : FeedbackUploader(is_off_the_record, state_path, url_loader_factory) {}

  void RunMessageLoop() {
    if (ProcessingComplete())
      return;
    run_loop_ = std::make_unique<base::RunLoop>();
    run_loop_->Run();
  }

  void SimulateLoadingOfflineReports() {
    task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(
            &FeedbackReport::LoadReportsAndQueue, feedback_reports_path(),
            base::BindRepeating(&MockFeedbackUploader::QueueSingleReport,
                                base::SequencedTaskRunnerHandle::Get(),
                                AsWeakPtr())));
  }

  const std::map<std::string, unsigned int>& dispatched_reports() const {
    return dispatched_reports_;
  }
  void set_expected_reports(size_t value) { expected_reports_ = value; }
  void set_simulate_failure(bool value) { simulate_failure_ = value; }

 private:
  static void QueueSingleReport(
      scoped_refptr<base::SequencedTaskRunner> main_task_runner,
      base::WeakPtr<FeedbackUploader> uploader,
      scoped_refptr<FeedbackReport> report) {
    main_task_runner->PostTask(
        FROM_HERE, base::BindOnce(&MockFeedbackUploader::RequeueReport,
                                  std::move(uploader), std::move(report)));
  }

  // FeedbackUploaderChrome:
  void StartDispatchingReport() override {
    if (base::Contains(dispatched_reports_, report_being_dispatched()->data()))
      dispatched_reports_[report_being_dispatched()->data()]++;
    else
      dispatched_reports_[report_being_dispatched()->data()] = 1;

    dispatched_reports_count_++;

    if (simulate_failure_)
      OnReportUploadFailure(true /* should_retry */);
    else
      OnReportUploadSuccess();

    if (ProcessingComplete()) {
      if (run_loop_)
        run_loop_->Quit();
    }
  }

  bool ProcessingComplete() {
    return (dispatched_reports_count_ >= expected_reports_);
  }

  std::unique_ptr<base::RunLoop> run_loop_;
  std::map<std::string, unsigned int> dispatched_reports_;
  size_t dispatched_reports_count_ = 0;
  size_t expected_reports_ = 0;
  bool simulate_failure_ = false;

  DISALLOW_COPY_AND_ASSIGN(MockFeedbackUploader);
};

}  // namespace

class FeedbackUploaderTest : public testing::Test {
 public:
  FeedbackUploaderTest() {
    FeedbackUploader::SetMinimumRetryDelayForTesting(kRetryDelayForTest);
    test_shared_loader_factory_ =
        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
            &test_url_loader_factory_);
    EXPECT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    RecreateUploader();
  }

  ~FeedbackUploaderTest() override = default;

  void RecreateUploader() {
    uploader_ = std::make_unique<MockFeedbackUploader>(
        /*is_off_the_record=*/false, scoped_temp_dir_.GetPath(),
        test_shared_loader_factory_);
  }

  void QueueReport(const std::string& data, bool has_email = true) {
    uploader_->QueueReport(std::make_unique<std::string>(data), has_email);
  }

  MockFeedbackUploader* uploader() const { return uploader_.get(); }

 private:
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
  base::test::TaskEnvironment task_environment_;
  base::ScopedTempDir scoped_temp_dir_;
  std::unique_ptr<MockFeedbackUploader> uploader_;

  DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderTest);
};

TEST_F(FeedbackUploaderTest, QueueMultiple) {
  QueueReport(kReportOne);
  QueueReport(kReportTwo);
  QueueReport(kReportThree);
  QueueReport(kReportFour);

  EXPECT_EQ(uploader()->dispatched_reports().size(), 4u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportOne), 1u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportTwo), 1u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportThree), 1u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportFour), 1u);
}

TEST_F(FeedbackUploaderTest, QueueMultipleWithFailures) {
  EXPECT_EQ(kRetryDelayForTest, uploader()->retry_delay());
  QueueReport(kReportOne);

  // Simulate a failure in reports two and three. Make sure the backoff delay
  // will be applied twice, and the reports will eventually be sent.
  uploader()->set_simulate_failure(true);
  QueueReport(kReportTwo);
  EXPECT_EQ(kRetryDelayForTest * 2, uploader()->retry_delay());
  QueueReport(kReportThree);
  EXPECT_EQ(kRetryDelayForTest * 4, uploader()->retry_delay());
  uploader()->set_simulate_failure(false);

  // Once a successful report is sent, the backoff delay is reset back to its
  // minimum value.
  QueueReport(kReportFour);
  EXPECT_EQ(kRetryDelayForTest, uploader()->retry_delay());
  QueueReport(kReportFive);

  // Wait for the pending two failed reports to be sent.
  uploader()->set_expected_reports(7);
  uploader()->RunMessageLoop();

  EXPECT_EQ(uploader()->dispatched_reports().size(), 5u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportOne), 1u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportTwo), 2u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportThree), 2u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportFour), 1u);
  EXPECT_EQ(uploader()->dispatched_reports().at(kReportFive), 1u);
}

#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
// https://crbug.com/1222877
#define MAYBE_SimulateOfflineReports DISABLED_SimulateOfflineReports
#else
#define MAYBE_SimulateOfflineReports SimulateOfflineReports
#endif
TEST_F(FeedbackUploaderTest, MAYBE_SimulateOfflineReports) {
  // Simulate offline reports by failing to upload three reports.
  uploader()->set_simulate_failure(true);
  QueueReport(kReportOne);
  QueueReport(kReportTwo);
  QueueReport(kReportThree);

  // All three reports will be attempted to be uploaded, but the uploader queue
  // will remain having three reports since they all failed.
  uploader()->set_expected_reports(3);
  uploader()->RunMessageLoop();
  EXPECT_EQ(uploader()->dispatched_reports().size(), 3u);
  EXPECT_FALSE(uploader()->QueueEmpty());

  // Simulate a sign out / resign in by recreating the uploader. This should not
  // clear any pending feedback report files on disk, and hence they can be
  // reloaded.
  RecreateUploader();
  uploader()->SimulateLoadingOfflineReports();
  uploader()->set_expected_reports(3);
  uploader()->RunMessageLoop();

  // The three reports were loaded, successfully uploaded, and the uploader
  // queue is now empty.
  EXPECT_EQ(uploader()->dispatched_reports().size(), 3u);
  EXPECT_TRUE(uploader()->QueueEmpty());
}

}  // namespace feedback
