/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>

#include <iosfwd>
#include <memory>
#include <string>
#include <vector>

#include "android-base/stringprintf.h"
#include "base/bit_utils.h"
#include "base/common_art_test.h"
#include "base/os.h"
#include "base/unix_file/fd_file.h"
#include "odr_fs_utils.h"

namespace art {
namespace odrefresh {

class OdrFsUtilsTest : public CommonArtTest {};
namespace {

static bool CreateFile(const char* file_path, size_t bytes) {
  std::unique_ptr<File> fp(OS::CreateEmptyFile(file_path));
  if (!fp) {
    return false;
  }

  std::vector<char> buffer(bytes, 0xa5);
  if (!fp->WriteFully(buffer.data(), buffer.size())) {
    fp->Erase();
    return false;
  }

  if (fp->FlushClose() != 0) {
    fp->Erase();
    return false;
  }

  return true;
}

}  // namespace

TEST_F(OdrFsUtilsTest, RemoveDirectory) {
  ScratchDir scratch_dir(/*keep_files=*/false);

  // Create some sub-directories and files
  const std::string dir_paths[] = {
      scratch_dir.GetPath() + "/a",
      scratch_dir.GetPath() + "/b",
      scratch_dir.GetPath() + "/b/c",
      scratch_dir.GetPath() + "/d"
  };
  for (const auto& dir_path : dir_paths) {
    ASSERT_EQ(0, mkdir(dir_path.c_str(), S_IRWXU));
  }

  const std::string file_paths[] = {
      scratch_dir.GetPath() + "/zero.txt",
      scratch_dir.GetPath() + "/a/one.txt",
      scratch_dir.GetPath() + "/b/two.txt",
      scratch_dir.GetPath() + "/b/c/three.txt",
      scratch_dir.GetPath() + "/b/c/four.txt",
  };
  for (const auto& file_path : file_paths) {
    ASSERT_TRUE(CreateFile(file_path.c_str(), 4096));
  }

  // Remove directory, all files and sub-directories
  ASSERT_TRUE(RemoveDirectory(scratch_dir.GetPath()));

  // Check nothing we created remains.
  for (const auto& dir_path : dir_paths) {
    ASSERT_FALSE(OS::DirectoryExists(dir_path.c_str()));
  }

  for (const auto& file_path : file_paths) {
    ASSERT_FALSE(OS::FileExists(file_path.c_str(), true));
  }

  // And the original directory is also gone
  ASSERT_FALSE(OS::DirectoryExists(scratch_dir.GetPath().c_str()));
}

TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsBadPath) {
  // Pick a path where not even a root test runner can write.
  ASSERT_FALSE(EnsureDirectoryExists("/proc/unlikely/to/be/writable"));
}

TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsEmptyPath) {
  ASSERT_FALSE(EnsureDirectoryExists(""));
}

TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsRelativePath) {
  ASSERT_FALSE(EnsureDirectoryExists("a/b/c"));
}

TEST_F(OdrFsUtilsTest, EnsureDirectoryExistsSubDirs) {
  ScratchDir scratch_dir(/*keep_files=*/false);

  const char* relative_sub_dirs[] = {"a", "b/c", "d/e/f/"};
  for (const char* relative_sub_dir : relative_sub_dirs) {
    ASSERT_TRUE(EnsureDirectoryExists(scratch_dir.GetPath() + "/" + relative_sub_dir));
  }
}

TEST_F(OdrFsUtilsTest, DISABLED_GetUsedSpace) {
  static constexpr size_t kFirstFileBytes = 1;
  static constexpr size_t kSecondFileBytes = 16111;
  static constexpr size_t kBytesPerBlock = 512;

  ScratchDir scratch_dir(/*keep_files=*/false);

  const std::string first_file_path = scratch_dir.GetPath() + "/1.dat";
  ASSERT_TRUE(CreateFile(first_file_path.c_str(), kFirstFileBytes));

  struct stat sb;
  ASSERT_EQ(0, stat(first_file_path.c_str(), &sb));
  ASSERT_EQ(kFirstFileBytes, static_cast<decltype(kFirstFileBytes)>(sb.st_size));

  uint64_t bytes_used = 0;
  ASSERT_TRUE(GetUsedSpace(scratch_dir.GetPath().c_str(), &bytes_used));

  const std::string second_file_path = scratch_dir.GetPath() + "/2.dat";
  ASSERT_TRUE(CreateFile(second_file_path.c_str(), kSecondFileBytes));

  ASSERT_TRUE(GetUsedSpace(scratch_dir.GetPath().c_str(), &bytes_used));
  uint64_t expected_bytes_used = RoundUp(kFirstFileBytes, sb.st_blocks * kBytesPerBlock) +
                                 RoundUp(kSecondFileBytes, sb.st_blocks * kBytesPerBlock);
  ASSERT_EQ(expected_bytes_used, bytes_used);

  const std::string sub_dir_path = scratch_dir.GetPath() + "/sub";
  ASSERT_TRUE(EnsureDirectoryExists(sub_dir_path));
  for (size_t i = 1; i < 32768; i *= 17) {
    const std::string path = android::base::StringPrintf("%s/%zu", sub_dir_path.c_str(), i);
    ASSERT_TRUE(CreateFile(path.c_str(), i));
    expected_bytes_used += RoundUp(i, sb.st_blocks * kBytesPerBlock);
    ASSERT_TRUE(GetUsedSpace(scratch_dir.GetPath().c_str(), &bytes_used));
    ASSERT_EQ(expected_bytes_used, bytes_used);
  }
}

TEST_F(OdrFsUtilsTest, GetUsedSpaceBadPath) {
  ScratchDir scratch_dir(/*keep_files=*/false);
  const std::string bad_path = scratch_dir.GetPath() + "/bad_path";
  uint64_t bytes_used = ~0ull;
  ASSERT_TRUE(GetUsedSpace(bad_path, &bytes_used));
  ASSERT_EQ(0ull, bytes_used);
}

}  // namespace odrefresh
}  // namespace art
