// Copyright 2014 The Chromium OS 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 "feedback/feedback_service.h"

#include <utime.h>

#include <string>
#include <vector>

#include <base/at_exit.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/guid.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/stringprintf.h>
#include <base/threading/thread.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "components/feedback/feedback_common.h"
#include "components/feedback/feedback_report.h"
#include "components/feedback/feedback_uploader.h"
#include "components/feedback/proto/extension.pb.h"

namespace feedback {

namespace {

static constexpr char kThreadName[] = "FeedbackWorkerThread";
static constexpr char kFeedbackReportPath[] = "Feedback Reports";
static constexpr int kTestProductId = 84;

}  // namespace

class MockFeedbackUploader : public feedback::FeedbackUploader {
 public:
  MockFeedbackUploader(const base::FilePath& path,
                       scoped_refptr<base::SingleThreadTaskRunner> task_runner)
      : FeedbackUploader(path, task_runner) {}

  MOCK_METHOD(void, DispatchReport, (const std::string&), (override));
};

class MockFeedbackUploaderQueue : public MockFeedbackUploader {
 public:
  MockFeedbackUploaderQueue(
      const base::FilePath& path,
      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
      : MockFeedbackUploader(path, task_runner) {}

  MOCK_METHOD(void, QueueReport, (const std::string&), (override));
};

class FailedFeedbackUploader : public MockFeedbackUploader {
 public:
  FailedFeedbackUploader(
      const base::FilePath& path,
      scoped_refptr<base::SingleThreadTaskRunner> task_runner)
      : MockFeedbackUploader(path, task_runner) {}

  void DispatchReport(const std::string& data) {
    MockFeedbackUploader::DispatchReport(data);
    RetryReport(data);
  }

  feedback::FeedbackReport* GetFirstReport() {
    scoped_refptr<feedback::FeedbackReport> report = reports_queue_.top();
    return report.get();
  }
};

class FeedbackServiceTest : public testing::Test {
 public:
  FeedbackServiceTest() : message_loop_(base::MessageLoop::TYPE_IO) {}

  static void CallbackFeedbackResult(bool expected_result, bool result,
                                     const std::string& err) {
    EXPECT_EQ(result, expected_result);
  }

  userfeedback::ExtensionSubmit GetBaseReport() {
    userfeedback::ExtensionSubmit report;
    report.mutable_common_data();
    report.mutable_web_data();
    report.set_type_id(0);
    report.set_product_id(kTestProductId);
    return report;
  }

  void WaitOnThread() { worker_thread_->FlushForTesting(); }

 protected:
  virtual void SetUp() {
    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
    CreateDirectory(temp_dir_.GetPath().Append(kFeedbackReportPath));

    worker_thread_ = std::make_unique<base::Thread>(kThreadName);
    worker_thread_->Start();
    worker_task_runner_ = worker_thread_->task_runner();
  }

  virtual void TearDown() {
    WaitOnThread();
    worker_thread_->Stop();
  }

  base::ScopedTempDir temp_dir_;
  base::MessageLoop message_loop_;
  std::unique_ptr<base::Thread> worker_thread_;
  scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_;
};

TEST_F(FeedbackServiceTest, SendFeedback) {
  MockFeedbackUploaderQueue uploader(temp_dir_.GetPath(), worker_task_runner_);
  std::string data;
  userfeedback::ExtensionSubmit report = GetBaseReport();
  report.SerializeToString(&data);
  EXPECT_CALL(uploader, QueueReport(data)).Times(1);

  scoped_refptr<FeedbackService> svc = new FeedbackService(&uploader);

  svc->SendFeedback(report,
      base::Bind(&FeedbackServiceTest::CallbackFeedbackResult, true));
}

TEST_F(FeedbackServiceTest, DispatchTest) {
  MockFeedbackUploader uploader(temp_dir_.GetPath(), worker_task_runner_);
  std::string data;
  userfeedback::ExtensionSubmit report = GetBaseReport();
  report.SerializeToString(&data);
  EXPECT_CALL(uploader, DispatchReport(data)).Times(1);

  scoped_refptr<FeedbackService> svc = new FeedbackService(&uploader);

  svc->SendFeedback(report,
      base::Bind(&FeedbackServiceTest::CallbackFeedbackResult, true));
}

TEST_F(FeedbackServiceTest, UploadFailure) {
  FailedFeedbackUploader uploader(temp_dir_.GetPath(), worker_task_runner_);
  std::string data;
  userfeedback::ExtensionSubmit report = GetBaseReport();
  report.SerializeToString(&data);
  EXPECT_CALL(uploader, DispatchReport(data)).Times(1);

  scoped_refptr<FeedbackService> svc = new FeedbackService(&uploader);

  svc->SendFeedback(report,
      base::Bind(&FeedbackServiceTest::CallbackFeedbackResult, true));
  WaitOnThread();

  // Verify that this got put back on the queue.
  EXPECT_TRUE(uploader.GetFirstReport() != nullptr);
  EXPECT_EQ(uploader.GetFirstReport()->data(), data);
}

}  // namespace feedback
