// Copyright 2011 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/file_reader.h"

#include <limits>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "components/crx_file/id_util.h"
#include "extensions/common/extension_paths.h"
#include "extensions/common/extension_resource.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace extensions {

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

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

 private:
  base::test::TaskEnvironment task_environment_;
};

class Receiver {
 public:
  explicit Receiver(
      std::vector<ExtensionResource> resources,
      size_t max_resources_length = std::numeric_limits<size_t>::max())
      : file_reader_(base::MakeRefCounted<FileReader>(
            std::move(resources),
            max_resources_length,
            FileReader::OptionalFileSequenceTask(),
            base::BindOnce(&Receiver::DidReadFile, base::Unretained(this)))) {}

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

  void Run() {
    file_reader_->Start();
    run_loop_.Run();
  }

  // Removes the pointer indirection from the read data for use with
  // comparators.
  std::vector<std::string> GetStringData() const {
    std::vector<std::string> string_data;
    string_data.reserve(data_.size());
    for (const auto& entry : data_) {
      EXPECT_TRUE(entry);
      string_data.push_back(*entry);
    }
    return string_data;
  }

  const absl::optional<std::string>& error() const { return error_; }
  bool succeeded() const { return !error_; }
  const std::vector<std::unique_ptr<std::string>>& data() const {
    return data_;
  }

 private:
  void DidReadFile(std::vector<std::unique_ptr<std::string>> data,
                   absl::optional<std::string> error) {
    error_ = std::move(error);
    data_ = std::move(data);
    run_loop_.QuitWhenIdle();
  }

  absl::optional<std::string> error_;
  std::vector<std::unique_ptr<std::string>> data_;
  scoped_refptr<FileReader> file_reader_;
  base::RunLoop run_loop_;
};

void RunBasicTest(const std::vector<std::string>& filenames) {
  base::FilePath root_path;
  base::PathService::Get(DIR_TEST_DATA, &root_path);
  std::string extension_id = crx_file::id_util::GenerateId("test");

  std::vector<ExtensionResource> resources;
  resources.reserve(filenames.size());
  std::vector<std::string> expected_contents;
  expected_contents.reserve(filenames.size());
  for (const auto& filename : filenames) {
    resources.emplace_back(extension_id, root_path,
                           base::FilePath().AppendASCII(filename));

    base::FilePath path = root_path.AppendASCII(filename);
    std::string file_contents;
    ASSERT_TRUE(base::ReadFileToString(path, &file_contents));
    expected_contents.push_back(std::move(file_contents));
  }

  Receiver receiver(resources);
  receiver.Run();

  EXPECT_TRUE(receiver.succeeded()) << *receiver.error();
  EXPECT_THAT(receiver.GetStringData(),
              ::testing::ElementsAreArray(expected_contents));
}

TEST_F(FileReaderTest, SmallFile) {
  RunBasicTest({"smallfile"});
}

TEST_F(FileReaderTest, BiggerFile) {
  RunBasicTest({"bigfile"});
}

TEST_F(FileReaderTest, MultiFile) {
  RunBasicTest({"smallfile", "bigfile"});
}

TEST_F(FileReaderTest, NonExistentFile) {
  base::FilePath path;
  base::PathService::Get(DIR_TEST_DATA, &path);
  std::string extension_id = crx_file::id_util::GenerateId("test");
  ExtensionResource resource(
      extension_id, path,
      base::FilePath(FILE_PATH_LITERAL("file_that_does_not_exist")));

  Receiver receiver({resource});
  receiver.Run();

  EXPECT_FALSE(receiver.succeeded());
  EXPECT_EQ("Could not load file: 'file_that_does_not_exist'.",
            *receiver.error());
}

TEST_F(FileReaderTest, AboveSizeLimitFile) {
  base::FilePath path;
  base::PathService::Get(DIR_TEST_DATA, &path);
  std::string extension_id = crx_file::id_util::GenerateId("test");

  ExtensionResource resource(extension_id, path,
                             base::FilePath().AppendASCII("bigfile"));

  Receiver receiver({resource}, /*max_resources_length=*/100u);
  receiver.Run();

  EXPECT_FALSE(receiver.succeeded());
  EXPECT_EQ("Could not load file: 'bigfile'. Resource size exceeded.",
            *receiver.error());
}

}  // namespace extensions
