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

#include <stddef.h>
#include <stdint.h>

#include <array>
#include <map>
#include <string>

#include "base/compiler_specific.h"
#include "base/test/task_environment.h"
#include "components/services/filesystem/directory_test_helper.h"
#include "components/services/filesystem/public/mojom/directory.mojom.h"
#include "components/services/filesystem/public/mojom/types.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace filesystem {
namespace {

class DirectoryImplTest : public testing::Test {
 public:
  DirectoryImplTest() = default;

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

  mojo::Remote<mojom::Directory> CreateTempDir() {
    return test_helper_.CreateTempDir();
  }

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

constexpr char kData[] = "one two three";

TEST_F(DirectoryImplTest, Read) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  // Make some files.
  struct FilesToCreate {
    const char* name;
    uint32_t open_flags;
  };
  const auto files_to_create = std::to_array<FilesToCreate>({
      {"my_file1", mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate},
      {"my_file2", mojom::kFlagWrite | mojom::kFlagCreate},
      {"my_file3", mojom::kFlagAppend | mojom::kFlagCreate},
  });
  for (size_t i = 0; i < std::size(files_to_create); i++) {
    error = base::File::Error::FILE_ERROR_FAILED;
    base::File tmp_base_file;
    bool handled = directory->OpenFileHandle(files_to_create[i].name,
                                             files_to_create[i].open_flags,
                                             &error, &tmp_base_file);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
    tmp_base_file.Close();
  }
  // Make a directory.
  error = base::File::Error::FILE_ERROR_FAILED;
  bool handled = directory->OpenDirectory(
      "my_dir", mojo::NullReceiver(),
      mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);

  error = base::File::Error::FILE_ERROR_FAILED;
  std::optional<std::vector<mojom::DirectoryEntryPtr>> directory_contents;
  handled = directory->Read(&error, &directory_contents);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);
  ASSERT_TRUE(directory_contents.has_value());

  // Expected contents of the directory.
  std::map<std::string, mojom::FsFileType> expected_contents;
  expected_contents["my_file1"] = mojom::FsFileType::REGULAR_FILE;
  expected_contents["my_file2"] = mojom::FsFileType::REGULAR_FILE;
  expected_contents["my_file3"] = mojom::FsFileType::REGULAR_FILE;
  expected_contents["my_dir"] = mojom::FsFileType::DIRECTORY;
  // Note: We don't expose ".." or ".".

  EXPECT_EQ(expected_contents.size(), directory_contents->size());
  for (size_t i = 0; i < directory_contents->size(); i++) {
    auto& item = directory_contents.value()[i];
    ASSERT_TRUE(item);
    auto it = expected_contents.find(item->name.AsUTF8Unsafe());
    ASSERT_TRUE(it != expected_contents.end());
    EXPECT_EQ(it->second, item->type);
    expected_contents.erase(it);
  }
}

// TODO(vtl): Properly test OpenDirectory() (including flags).

TEST_F(DirectoryImplTest, BasicRenameDelete) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  // Create my_file.
  error = base::File::Error::FILE_ERROR_FAILED;
  base::File tmp_base_file;
  bool handled = directory->OpenFileHandle(
      "my_file", mojom::kFlagWrite | mojom::kFlagCreate, &error,
      &tmp_base_file);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);

  // Opening my_file should succeed.
  error = base::File::Error::FILE_ERROR_FAILED;
  handled = directory->OpenFileHandle(
      "my_file", mojom::kFlagRead | mojom::kFlagOpen, &error, &tmp_base_file);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);
  tmp_base_file.Close();

  // Rename my_file to my_new_file.
  handled = directory->Rename("my_file", "my_new_file", &error);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);

  // Opening my_file should fail.
  error = base::File::Error::FILE_ERROR_FAILED;
  handled = directory->OpenFileHandle(
      "my_file", mojom::kFlagRead | mojom::kFlagOpen, &error, &tmp_base_file);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND, error);
  tmp_base_file.Close();

  // Opening my_new_file should succeed.
  error = base::File::Error::FILE_ERROR_FAILED;
  handled = directory->OpenFileHandle("my_new_file",
                                      mojom::kFlagRead | mojom::kFlagOpen,
                                      &error, &tmp_base_file);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);
  tmp_base_file.Close();

  // Delete my_new_file (no flags).
  handled = directory->Delete("my_new_file", 0, &error);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_OK, error);
  tmp_base_file.Close();

  // Opening my_new_file should fail.
  error = base::File::Error::FILE_ERROR_FAILED;
  handled = directory->OpenFileHandle("my_new_file",
                                      mojom::kFlagRead | mojom::kFlagOpen,
                                      &error, &tmp_base_file);
  ASSERT_TRUE(handled);
  EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND, error);
  tmp_base_file.Close();
}

TEST_F(DirectoryImplTest, CantOpenDirectoriesAsFiles) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  {
    // Create a directory called 'my_file'
    mojo::Remote<mojom::Directory> my_file_directory;
    error = base::File::Error::FILE_ERROR_FAILED;
    bool handled = directory->OpenDirectory(
        "my_file", my_file_directory.BindNewPipeAndPassReceiver(),
        mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
  }

  {
    // Attempt to open that directory as a file. This must fail!
    base::File tmp_file_handle;
    error = base::File::Error::FILE_ERROR_FAILED;
    bool handled = directory->OpenFileHandle(
        "my_file", mojom::kFlagRead | mojom::kFlagOpen, &error,
        &tmp_file_handle);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_A_FILE, error);
  }
}

TEST_F(DirectoryImplTest, Clone) {
  mojo::Remote<mojom::Directory> clone_one;
  mojo::Remote<mojom::Directory> clone_two;
  base::File::Error error;

  {
    mojo::Remote<mojom::Directory> directory = CreateTempDir();
    directory->Clone(clone_one.BindNewPipeAndPassReceiver());
    directory->Clone(clone_two.BindNewPipeAndPassReceiver());

    // Original temporary directory goes out of scope here; shouldn't be
    // deleted since it has clones.
  }

  std::vector<uint8_t> data(kData, UNSAFE_TODO(kData + strlen(kData)));
  {
    bool handled = clone_one->WriteFile("data", data, &error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
  }

  {
    std::vector<uint8_t> file_contents;
    bool handled = clone_two->ReadEntireFile("data", &error, &file_contents);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);

    EXPECT_EQ(data, file_contents);
  }
}

TEST_F(DirectoryImplTest, WriteFileReadFile) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  std::vector<uint8_t> data(kData, UNSAFE_TODO(kData + strlen(kData)));
  {
    bool handled = directory->WriteFile("data", data, &error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
  }

  {
    std::vector<uint8_t> file_contents;
    bool handled = directory->ReadEntireFile("data", &error, &file_contents);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);

    EXPECT_EQ(data, file_contents);
  }
}

TEST_F(DirectoryImplTest, ReadEmptyFileIsNotFoundError) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  {
    std::vector<uint8_t> file_contents;
    bool handled =
        directory->ReadEntireFile("doesnt_exist", &error, &file_contents);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_FOUND, error);
  }
}

TEST_F(DirectoryImplTest, CantReadEntireFileOnADirectory) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  // Create a directory
  {
    mojo::Remote<mojom::Directory> my_file_directory;
    error = base::File::Error::FILE_ERROR_FAILED;
    bool handled = directory->OpenDirectory(
        "my_dir", my_file_directory.BindNewPipeAndPassReceiver(),
        mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
  }

  // Try to read it as a file
  {
    std::vector<uint8_t> file_contents;
    bool handled = directory->ReadEntireFile("my_dir", &error, &file_contents);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_A_FILE, error);
  }
}

TEST_F(DirectoryImplTest, CantWriteFileOnADirectory) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  // Create a directory
  {
    mojo::Remote<mojom::Directory> my_file_directory;
    error = base::File::Error::FILE_ERROR_FAILED;
    bool handled = directory->OpenDirectory(
        "my_dir", my_file_directory.BindNewPipeAndPassReceiver(),
        mojom::kFlagRead | mojom::kFlagWrite | mojom::kFlagCreate, &error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
  }

  {
    std::vector<uint8_t> data(kData, UNSAFE_TODO(kData + strlen(kData)));
    bool handled = directory->WriteFile("my_dir", data, &error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_ERROR_NOT_A_FILE, error);
  }
}

TEST_F(DirectoryImplTest, Flush) {
  mojo::Remote<mojom::Directory> directory = CreateTempDir();
  base::File::Error error;

  {
    bool handled = directory->Flush(&error);
    ASSERT_TRUE(handled);
    EXPECT_EQ(base::File::Error::FILE_OK, error);
  }
}

}  // namespace
}  // namespace filesystem
