// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include <string>
#include <vector>

#include <base/string_util.h>
#include <gtest/gtest.h>

#include "update_engine/graph_types.h"
#include "update_engine/delta_diff_generator.h"
#include "update_engine/metadata.h"
#include "update_engine/test_utils.h"
#include "update_engine/utils.h"

using std::string;
using std::vector;

namespace chromeos_update_engine {

typedef DeltaDiffGenerator::Block Block;

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

TEST_F(MetadataTest, RunAsRootReadMetadataDissimilarFileSystems) {
  string a_img, b_img;
  EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
  ScopedPathUnlinker a_img_unlinker(a_img);
  EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
  ScopedPathUnlinker b_img_unlinker(b_img);

  CreateEmptyExtImageAtPath(a_img, 10485759, 4096);
  CreateEmptyExtImageAtPath(b_img, 11534336, 4096);

  Graph graph;
  vector<Block> blocks;
  EXPECT_TRUE(Metadata::DeltaReadMetadata(&graph,
                                          &blocks,
                                          a_img,
                                          b_img,
                                          0,
                                          NULL));
  EXPECT_EQ(graph.size(), 0);

  CreateEmptyExtImageAtPath(a_img, 10485759, 4096);
  CreateEmptyExtImageAtPath(b_img, 10485759, 8192);

  graph.clear();
  blocks.clear();
  EXPECT_TRUE(Metadata::DeltaReadMetadata(&graph,
                                          &blocks,
                                          a_img,
                                          b_img,
                                          0,
                                          NULL));
  EXPECT_EQ(graph.size(), 0);
}

TEST_F(MetadataTest, RunAsRootReadMetadata) {
  string a_img, b_img, data_file;
  EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
  ScopedPathUnlinker a_img_unlinker(a_img);
  EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
  ScopedPathUnlinker b_img_unlinker(b_img);
  EXPECT_TRUE(utils::MakeTempFile("/tmp/data_file.XXXXXX", &data_file, NULL));
  ScopedPathUnlinker data_file_unlinker(data_file);

  const size_t image_size = (256 * 1024 * 1024);  // Enough for 2 block groups
  const int block_size = 4096;
  CreateEmptyExtImageAtPath(a_img, image_size, block_size);

  // Create a file large enough to create an indirect block
  {
    string a_img_mnt;
    ScopedLoopMounter a_img_mount(a_img, &a_img_mnt, 0);
    System(StringPrintf("dd if=/dev/zero of=%s/test_file bs=%d count=%d",
                        a_img_mnt.c_str(), block_size, EXT2_NDIR_BLOCKS + 1));
  }

  System(StringPrintf("cp %s %s", a_img.c_str(), b_img.c_str()));

  int fd = open(data_file.c_str(), O_RDWR | O_CREAT, S_IRWXU);
  EXPECT_NE(fd, -1);
  ScopedFdCloser fd_closer(&fd);

  Graph graph;
  vector<Block> blocks(image_size / block_size);
  off_t data_file_size;
  EXPECT_TRUE(Metadata::DeltaReadMetadata(&graph,
                                          &blocks,
                                          a_img,
                                          b_img,
                                          fd,
                                          &data_file_size));

  // There are 12 metadata that we look for:
  //   - Block group 0 metadata (superblock, group descriptor, bitmaps, etc)
  //       - Chunk 0, 1, 2, 3
  //   - Block group 1 metadata
  //       - Chunk 0, 1, 2, 3
  //   - Root directory (inode 2)
  //   - Journal (inode 8)
  //   - lost+found directory (inode 11)
  //   - test_file indirect block (inode 12)
  struct {
    string metadata_name;
    off_t start_block; // Set to -1 to skip start block verification
    off_t num_blocks; // Set to -1 to skip num blocks verification
  } exp_results[] =
      {{"<rootfs-bg-0-0-metadata>", 0, 104},
       {"<rootfs-bg-0-1-metadata>", 104, 104},
       {"<rootfs-bg-0-2-metadata>", 208, 104},
       {"<rootfs-bg-0-3-metadata>", 312, 104},
       {"<rootfs-bg-0-4-metadata>", 416, 104},
       {"<rootfs-bg-0-5-metadata>", 520, 104},
       {"<rootfs-bg-0-6-metadata>", 624, 104},
       {"<rootfs-bg-0-7-metadata>", 728, 104},
       {"<rootfs-bg-0-8-metadata>", 832, 104},
       {"<rootfs-bg-0-9-metadata>", 936, 107},
       {"<rootfs-bg-1-0-metadata>", 32768, 104},
       {"<rootfs-bg-1-1-metadata>", 32872, 104},
       {"<rootfs-bg-1-2-metadata>", 32976, 104},
       {"<rootfs-bg-1-3-metadata>", 33080, 104},
       {"<rootfs-bg-1-4-metadata>", 33184, 104},
       {"<rootfs-bg-1-5-metadata>", 33288, 104},
       {"<rootfs-bg-1-6-metadata>", 33392, 104},
       {"<rootfs-bg-1-7-metadata>", 33496, 104},
       {"<rootfs-bg-1-8-metadata>", 33600, 104},
       {"<rootfs-bg-1-9-metadata>", 33704, 107},
       {"<rootfs-inode-2-metadata>", -1, 1},
       {"<rootfs-inode-8-metadata>", -1, 4101},
       {"<rootfs-inode-11-metadata>", -1, 4},
       {"<rootfs-inode-12-metadata>", -1, 1}};

  int num_exp_results = sizeof(exp_results) / sizeof(exp_results[0]);
  EXPECT_EQ(graph.size(), num_exp_results);

  for (int i = 0; i < num_exp_results; i++) {
    Vertex& vertex = graph[i];
    DeltaArchiveManifest_InstallOperation& op = vertex.op;

    EXPECT_STRCASEEQ(vertex.file_name.c_str(),
                     exp_results[i].metadata_name.c_str());

    EXPECT_EQ(op.src_extents().size(), op.dst_extents().size());
    for (int e = 0; e < op.src_extents().size(); e++) {
      EXPECT_EQ(op.src_extents(e).start_block(),
                op.dst_extents(e).start_block());
      EXPECT_EQ(op.src_extents(e).num_blocks(),
                op.dst_extents(e).num_blocks());
    }

    if (exp_results[i].start_block != -1) {
      EXPECT_EQ(op.src_extents(0).start_block(), exp_results[i].start_block);
    }

    if (exp_results[i].num_blocks != -1) {
      EXPECT_EQ(op.src_extents(0).num_blocks(), exp_results[i].num_blocks);
    }
  }
}

}  // namespace chromeos_update_engine
