//
// Copyright (C) 2015 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 "update_engine/payload_generator/ext2_filesystem.h"

#include <unistd.h>

#include <map>
#include <set>
#include <string>
#include <vector>

#include <base/format_macros.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>

#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/payload_generator/extent_utils.h"

using chromeos_update_engine::test_utils::GetBuildArtifactsPath;
using std::map;
using std::set;
using std::string;
using std::unique_ptr;
using std::vector;

namespace chromeos_update_engine {

namespace {

uint64_t kDefaultFilesystemSize = 4 * 1024 * 1024;
size_t kDefaultFilesystemBlockCount = 1024;
size_t kDefaultFilesystemBlockSize = 4096;

// Checks that all the blocks in |extents| are in the range [0, total_blocks).
void ExpectBlocksInRange(const vector<Extent>& extents, uint64_t total_blocks) {
  for (const Extent& extent : extents) {
    EXPECT_LE(0U, extent.start_block());
    EXPECT_LE(extent.start_block() + extent.num_blocks(), total_blocks);
  }
}

}  // namespace

class Ext2FilesystemTest : public ::testing::Test {};

TEST_F(Ext2FilesystemTest, InvalidFilesystem) {
  test_utils::ScopedTempFile fs_filename_{"Ext2FilesystemTest-XXXXXX"};
  ASSERT_EQ(0, truncate(fs_filename_.path().c_str(), kDefaultFilesystemSize));
  unique_ptr<Ext2Filesystem> fs =
      Ext2Filesystem::CreateFromFile(fs_filename_.path());
  ASSERT_EQ(nullptr, fs.get());

  fs = Ext2Filesystem::CreateFromFile("/path/to/invalid/file");
  ASSERT_EQ(nullptr, fs.get());
}

TEST_F(Ext2FilesystemTest, EmptyFilesystem) {
  unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(
      GetBuildArtifactsPath("gen/disk_ext2_4k_empty.img"));

  ASSERT_NE(nullptr, fs.get());
  EXPECT_EQ(kDefaultFilesystemBlockCount, fs->GetBlockCount());
  EXPECT_EQ(kDefaultFilesystemBlockSize, fs->GetBlockSize());

  vector<FilesystemInterface::File> files;
  EXPECT_TRUE(fs->GetFiles(&files));

  map<string, FilesystemInterface::File> map_files;
  for (const auto& file : files) {
    EXPECT_EQ(map_files.end(), map_files.find(file.name))
        << "File " << file.name << " repeated in the list.";
    map_files[file.name] = file;
    ExpectBlocksInRange(file.extents, fs->GetBlockCount());
  }
  EXPECT_EQ(2U, map_files["/"].file_stat.st_ino);
  EXPECT_FALSE(map_files["<free-space>"].extents.empty());
}

// This test parses the sample images generated during build time with the
// "generate_image.sh" script. The expected conditions of each file in these
// images is encoded in the file name, as defined in the mentioned script.
TEST_F(Ext2FilesystemTest, ParseGeneratedImages) {
  const vector<string> kGeneratedImages = {
      "disk_ext2_1k.img",
      "disk_ext2_4k.img" };
  base::FilePath build_path = GetBuildArtifactsPath().Append("gen");
  for (const string& fs_name : kGeneratedImages) {
    LOG(INFO) << "Testing " << fs_name;
    unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(
        build_path.Append(fs_name).value());
    ASSERT_NE(nullptr, fs.get());

    vector<FilesystemInterface::File> files;
    map<string, FilesystemInterface::File> map_files;
    set<string> filenames;
    EXPECT_TRUE(fs->GetFiles(&files));
    for (const auto& file : files) {
      // Check no repeated files. We should parse hard-links with two different
      // names.
      EXPECT_EQ(map_files.end(), map_files.find(file.name))
          << "File " << file.name << " repeated in the list.";
      map_files[file.name] = file;
      filenames.insert(file.name);
      ExpectBlocksInRange(file.extents, fs->GetBlockCount());
    }

    // Check that all the files are parsed, and the /removed file should not
    // be included in the list.
    set<string> kExpectedFiles = {
        "/",
        "/cdev",
        "/dir1",
        "/dir1/file",
        "/dir1/dir2",
        "/dir1/dir2/file",
        "/dir1/dir2/dir1",
        "/empty-file",
        "/fifo",
        "/link-hard-regular-16k",
        "/link-long_symlink",
        "/link-short_symlink",
        "/lost+found",
        "/regular-small",
        "/regular-16k",
        "/regular-32k-zeros",
        "/regular-with_net_cap",
        "/sparse_empty-10k",
        "/sparse_empty-2blocks",
        "/sparse-10000blocks",
        "/sparse-16k-last_block",
        "/sparse-16k-first_block",
        "/sparse-16k-holes",
        "<inode-blocks>",
        "<free-space>",
        "<group-descriptors>",
    };
    EXPECT_EQ(kExpectedFiles, filenames);

    FilesystemInterface::File file;

    // Small symlinks don't actually have data blocks.
    EXPECT_TRUE(map_files["/link-short_symlink"].extents.empty());
    EXPECT_EQ(1U, BlocksInExtents(map_files["/link-long_symlink"].extents));

    // Hard-links report the same list of blocks.
    EXPECT_EQ(map_files["/link-hard-regular-16k"].extents,
              map_files["/regular-16k"].extents);
    EXPECT_FALSE(map_files["/regular-16k"].extents.empty());

    // The number of blocks in these files doesn't depend on the
    // block size.
    EXPECT_TRUE(map_files["/empty-file"].extents.empty());
    EXPECT_EQ(1U, BlocksInExtents(map_files["/regular-small"].extents));
    EXPECT_EQ(1U, BlocksInExtents(map_files["/regular-with_net_cap"].extents));
    EXPECT_TRUE(map_files["/sparse_empty-10k"].extents.empty());
    EXPECT_TRUE(map_files["/sparse_empty-2blocks"].extents.empty());
    EXPECT_EQ(1U, BlocksInExtents(map_files["/sparse-16k-last_block"].extents));
    EXPECT_EQ(1U,
              BlocksInExtents(map_files["/sparse-16k-first_block"].extents));
    EXPECT_EQ(2U, BlocksInExtents(map_files["/sparse-16k-holes"].extents));
  }
}

TEST_F(Ext2FilesystemTest, LoadSettingsFailsTest) {
  unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(
      GetBuildArtifactsPath("gen/disk_ext2_1k.img"));
  ASSERT_NE(nullptr, fs.get());

  brillo::KeyValueStore store;
  // disk_ext2_1k.img doesn't have the /etc/update_engine.conf file.
  EXPECT_FALSE(fs->LoadSettings(&store));
}

TEST_F(Ext2FilesystemTest, LoadSettingsWorksTest) {
  unique_ptr<Ext2Filesystem> fs = Ext2Filesystem::CreateFromFile(
      GetBuildArtifactsPath("gen/disk_ext2_unittest.img"));
  ASSERT_NE(nullptr, fs.get());

  brillo::KeyValueStore store;
  EXPECT_TRUE(fs->LoadSettings(&store));
  string minor_version;
  EXPECT_TRUE(store.GetString("PAYLOAD_MINOR_VERSION", &minor_version));
  EXPECT_EQ("1234", minor_version);
}

}  // namespace chromeos_update_engine
