// Copyright 2015 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/at_exit.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "mojo/common/data_pipe_utils.h"
#include "mojo/common/message_pump_mojo.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
#include "shell/crash/crash_upload.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace breakpad {
namespace {

class MockURLLoader : public mojo::URLLoader {
 public:
  MockURLLoader() : called_(false) {}
  ~MockURLLoader() override {}

  bool called() const { return called_; }

  std::string GetLastContent() {
    std::string result;
    mojo::common::BlockingCopyToString(body_.Pass(), &result);
    return result;
  }

 private:
  // Overriden from mojo::NetworkService.
  void Start(mojo::URLRequestPtr request,
             const StartCallback& callback) override {
    called_ = true;
    mojo::URLResponsePtr response = mojo::URLResponse::New();
    response->status_code = 200;
    body_ = request->body[0].Pass();
    callback.Run(response.Pass());
  }
  void FollowRedirect(const FollowRedirectCallback& callback) override {}
  void QueryStatus(const QueryStatusCallback& callback) override {}

  bool called_;
  mojo::ScopedDataPipeConsumerHandle body_;
};

class MockNetworkService : public mojo::NetworkService {
 public:
  MockNetworkService() : binding_(&mock_url_loader_) {}
  ~MockNetworkService() override {}

  MockURLLoader* url_loader() { return &mock_url_loader_; }

 private:
  // Overriden from mojo::NetworkService.
  void CreateURLLoader(
      mojo::InterfaceRequest<mojo::URLLoader> loader) override {
    binding_.Bind(loader.Pass());
  }
  void GetCookieStore(
      mojo::InterfaceRequest<mojo::CookieStore> cookie_store) override {}
  void CreateWebSocket(
      mojo::InterfaceRequest<mojo::WebSocket> socket) override {}
  void CreateTCPBoundSocket(
      mojo::NetAddressPtr local_address,
      mojo::InterfaceRequest<mojo::TCPBoundSocket> bound_socket,
      const CreateTCPBoundSocketCallback& callback) override {}
  void CreateTCPConnectedSocket(
      mojo::NetAddressPtr remote_address,
      mojo::ScopedDataPipeConsumerHandle send_stream,
      mojo::ScopedDataPipeProducerHandle receive_stream,
      mojo::InterfaceRequest<mojo::TCPConnectedSocket> client_socket,
      const CreateTCPConnectedSocketCallback& callback) override {}
  void CreateUDPSocket(
      mojo::InterfaceRequest<mojo::UDPSocket> socket) override {}
  void CreateHttpServer(mojo::NetAddressPtr local_address,
                        mojo::HttpServerDelegatePtr delegate,
                        const CreateHttpServerCallback& callback) override {}
  void RegisterURLLoaderInterceptor(
      mojo::URLLoaderInterceptorFactoryPtr factory) override {}
  void CreateHostResolver(
      mojo::InterfaceRequest<mojo::HostResolver> host_resolver) override {}

  MockURLLoader mock_url_loader_;
  mojo::Binding<mojo::URLLoader> binding_;
};

std::string GetDumpContent(const base::FilePath& path) {
  return "--" + path.value() + "\r\n";
}

void CreateValidDump(const base::FilePath& path, const base::Time& time) {
  std::string content = GetDumpContent(path);
  base::WriteFile(path, content.data(), content.size());
  base::TouchFile(path, time, time);
}

int CountFiles(const base::FilePath& path) {
  base::FileEnumerator files(path, false, base::FileEnumerator::FILES);
  int result = 0;
  for (base::FilePath file = files.Next(); !file.empty(); file = files.Next())
    ++result;
  return result;
}

base::FilePath GetSentinelPath(const base::FilePath& path) {
  return path.Append("upload.sentinel");
}

class CrashUploadTest : public testing::Test {
 public:
  CrashUploadTest()
      : loop_(mojo::common::MessagePumpMojo::Create()),
        binding_(&mock_network_service_, GetProxy(&network_service_)) {}

  void SetUp() override { ASSERT_TRUE(dumps_dir_.CreateUniqueTempDir()); }

  void RebindNetworkService() {
    binding_.Close();
    binding_.Bind(GetProxy(&network_service_));
  }

 protected:
  base::ShadowingAtExitManager at_exit_;
  base::MessageLoop loop_;
  MockNetworkService mock_network_service_;
  mojo::NetworkServicePtr network_service_;
  mojo::Binding<mojo::NetworkService> binding_;
  base::ScopedTempDir dumps_dir_;
};

// Tests that reports can be uploaded and that only the most recent report is
// uploaded.
TEST_F(CrashUploadTest, UploadToServer) {
  for (int i = 0; i < 3; ++i) {
    CreateValidDump(dumps_dir_.path().Append(base::StringPrintf("%d.dmp", i)),
                    base::Time::Now() - base::TimeDelta::FromHours(i));
  }

  UploadCrashes(dumps_dir_.path(), loop_.task_runner().get(),
                network_service_.Pass());
  loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
  base::RunLoop().Run();

  EXPECT_TRUE(mock_network_service_.url_loader()->called());
  EXPECT_TRUE(base::PathExists(GetSentinelPath(dumps_dir_.path())));
  EXPECT_EQ(GetDumpContent(dumps_dir_.path().Append("0.dmp")),
            mock_network_service_.url_loader()->GetLastContent());
  EXPECT_EQ(1, CountFiles(dumps_dir_.path()));
}

// Tests that nothing happen when there is nothing to upload.
TEST_F(CrashUploadTest, NothingToUpload) {
  UploadCrashes(dumps_dir_.path(), loop_.task_runner().get(),
                network_service_.Pass());
  loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
  base::RunLoop().Run();

  EXPECT_FALSE(mock_network_service_.url_loader()->called());
  EXPECT_EQ(0, CountFiles(dumps_dir_.path()));
}

// Tests that spurious reports are deleted but none are uploaded when there is a
// recent sentinel file. Check that the report is uploaded when the sentinel is
// old enough.
TEST_F(CrashUploadTest, UploadGuardedBySentinel) {
  for (int i = 0; i < 3; ++i) {
    CreateValidDump(dumps_dir_.path().Append(base::StringPrintf("%d.dmp", i)),
                    base::Time::Now() - base::TimeDelta::FromHours(i));
  }
  base::FilePath sentinel = GetSentinelPath(dumps_dir_.path());
  base::WriteFile(sentinel, nullptr, 0);
  base::TouchFile(sentinel,
                  base::Time::Now() - base::TimeDelta::FromMinutes(30),
                  base::Time::Now() - base::TimeDelta::FromMinutes(30));

  UploadCrashes(dumps_dir_.path(), loop_.task_runner().get(),
                network_service_.Pass());
  loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
  base::RunLoop().Run();

  EXPECT_FALSE(mock_network_service_.url_loader()->called());
  EXPECT_TRUE(base::PathExists(GetSentinelPath(dumps_dir_.path())));
  EXPECT_EQ(2, CountFiles(dumps_dir_.path()));

  // Send the sentinel in the past.
  base::TouchFile(sentinel,
                  base::Time::Now() - base::TimeDelta::FromMinutes(90),
                  base::Time::Now() - base::TimeDelta::FromMinutes(90));

  RebindNetworkService();
  UploadCrashes(dumps_dir_.path(), loop_.task_runner().get(),
                network_service_.Pass());
  loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
  base::RunLoop().Run();

  EXPECT_TRUE(mock_network_service_.url_loader()->called());
  EXPECT_TRUE(base::PathExists(GetSentinelPath(dumps_dir_.path())));
  EXPECT_EQ(GetDumpContent(dumps_dir_.path().Append("0.dmp")),
            mock_network_service_.url_loader()->GetLastContent());
  EXPECT_EQ(1, CountFiles(dumps_dir_.path()));
}

}  // namespace
}  // namespace breakpad
