// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/browser/json_file_sanitizer.h"

#include <memory>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/extension_file_task_runner.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace {

class JsonFileSanitizerTest : public testing::Test {
 public:
  JsonFileSanitizerTest() {}

  JsonFileSanitizerTest(const JsonFileSanitizerTest&) = delete;
  JsonFileSanitizerTest& operator=(const JsonFileSanitizerTest&) = delete;

 protected:
  base::FilePath CreateFilePath(const base::FilePath::StringType& file_name) {
    return temp_dir_.GetPath().Append(file_name);
  }

  void CreateValidJsonFile(const base::FilePath& path) {
    std::string kJson = "{\"hello\":\"bonjour\"}";
    ASSERT_TRUE(base::WriteFile(path, kJson));
  }

  void CreateInvalidJsonFile(const base::FilePath& path) {
    std::string kJson = "sjkdsk;'<?js";
    ASSERT_TRUE(base::WriteFile(path, kJson));
  }

  const base::FilePath& GetJsonFilePath() const { return temp_dir_.GetPath(); }

  void WaitForSanitizationDone() {
    ASSERT_FALSE(done_callback_);
    base::RunLoop run_loop;
    done_callback_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void CreateAndStartSanitizer(const std::set<base::FilePath>& file_paths) {
    sanitizer_ = JsonFileSanitizer::CreateAndStart(
        &data_decoder_, file_paths,
        base::BindOnce(&JsonFileSanitizerTest::SanitizationDone,
                       base::Unretained(this)),
        GetExtensionFileTaskRunner());
  }

  JsonFileSanitizer::Status last_reported_status() const {
    return last_status_;
  }

  const std::string& last_reported_error() const { return last_error_; }

 private:
  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }

  void SanitizationDone(JsonFileSanitizer::Status status,
                        const std::string& error_msg) {
    last_status_ = status;
    last_error_ = error_msg;
    if (done_callback_)
      std::move(done_callback_).Run();
  }

  content::BrowserTaskEnvironment task_environment_;
  data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
  data_decoder::DataDecoder data_decoder_;
  JsonFileSanitizer::Status last_status_;
  std::string last_error_;
  base::OnceClosure done_callback_;
  std::unique_ptr<JsonFileSanitizer> sanitizer_;
  base::ScopedTempDir temp_dir_;
};

}  // namespace

TEST_F(JsonFileSanitizerTest, NoFilesProvided) {
  CreateAndStartSanitizer(std::set<base::FilePath>());
  WaitForSanitizationDone();
  EXPECT_EQ(last_reported_status(), JsonFileSanitizer::Status::kSuccess);
  EXPECT_TRUE(last_reported_error().empty());
}

TEST_F(JsonFileSanitizerTest, ValidCase) {
  constexpr std::array<const base::FilePath::CharType* const, 10> kFileNames{
      {FILE_PATH_LITERAL("test0"), FILE_PATH_LITERAL("test1"),
       FILE_PATH_LITERAL("test2"), FILE_PATH_LITERAL("test3"),
       FILE_PATH_LITERAL("test4"), FILE_PATH_LITERAL("test5"),
       FILE_PATH_LITERAL("test6"), FILE_PATH_LITERAL("test7"),
       FILE_PATH_LITERAL("test8"), FILE_PATH_LITERAL("test9")}};
  std::set<base::FilePath> paths;
  for (const base::FilePath::CharType* file_name : kFileNames) {
    base::FilePath path = CreateFilePath(file_name);
    CreateValidJsonFile(path);
    paths.insert(path);
  }
  CreateAndStartSanitizer(paths);
  WaitForSanitizationDone();
  EXPECT_EQ(last_reported_status(), JsonFileSanitizer::Status::kSuccess);
  EXPECT_TRUE(last_reported_error().empty());
  // Make sure the JSON files are there and non empty.
  for (const auto& path : paths) {
    int64_t file_size = 0;
    EXPECT_TRUE(base::GetFileSize(path, &file_size));
    EXPECT_GT(file_size, 0);
  }
}

TEST_F(JsonFileSanitizerTest, MissingJsonFile) {
  constexpr base::FilePath::CharType kGoodName[] =
      FILE_PATH_LITERAL("i_exists");
  constexpr base::FilePath::CharType kNonExistingName[] =
      FILE_PATH_LITERAL("i_don_t_exist");
  base::FilePath good_path = CreateFilePath(kGoodName);
  CreateValidJsonFile(good_path);
  base::FilePath invalid_path = CreateFilePath(kNonExistingName);
  CreateAndStartSanitizer({good_path, invalid_path});
  WaitForSanitizationDone();
  EXPECT_EQ(last_reported_status(), JsonFileSanitizer::Status::kFileReadError);
}

TEST_F(JsonFileSanitizerTest, InvalidJson) {
  constexpr base::FilePath::CharType kGoodJsonFileName[] =
      FILE_PATH_LITERAL("good.json");
  constexpr base::FilePath::CharType kBadJsonFileName[] =
      FILE_PATH_LITERAL("bad.json");
  base::FilePath good_path = CreateFilePath(kGoodJsonFileName);
  CreateValidJsonFile(good_path);
  base::FilePath badd_path = CreateFilePath(kBadJsonFileName);
  CreateInvalidJsonFile(badd_path);
  CreateAndStartSanitizer({good_path, badd_path});
  WaitForSanitizationDone();
  EXPECT_EQ(last_reported_status(), JsonFileSanitizer::Status::kDecodingError);
  EXPECT_FALSE(last_reported_error().empty());
}

}  // namespace extensions
