// Copyright (c) 2009 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 "update_engine/test_utils.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

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

#include "base/string_util.h"
#include "base/logging.h"
#include "update_engine/file_writer.h"
#include "update_engine/filesystem_iterator.h"
#include "update_engine/utils.h"

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

namespace chromeos_update_engine {

bool WriteFileVector(const std::string& path, const std::vector<char>& data) {
  return utils::WriteFile(path.c_str(), &data[0], data.size());
}

bool WriteFileString(const std::string& path, const std::string& data) {
  return utils::WriteFile(path.c_str(), data.data(), data.size());
}

std::string Readlink(const std::string& path) {
  vector<char> buf(PATH_MAX + 1);
  ssize_t r = readlink(path.c_str(), &buf[0], buf.size());
  if (r < 0)
    return "";
  CHECK_LT(r, static_cast<ssize_t>(buf.size()));
  buf.resize(r);
  string ret;
  ret.insert(ret.begin(), buf.begin(), buf.end());
  return ret;
}

std::vector<char> GzipCompressData(const std::vector<char>& data) {
  const char fname[] = "/tmp/GzipCompressDataTemp";
  if (!WriteFileVector(fname, data)) {
    EXPECT_EQ(0, system((string("rm ") + fname).c_str()));
    return vector<char>();
  }
  EXPECT_EQ(0, system((string("cat ") + fname + "|gzip>" +
                       fname + ".gz").c_str()));
  EXPECT_EQ(0, system((string("rm ") + fname).c_str()));
  vector<char> ret;
  EXPECT_TRUE(utils::ReadFile(string(fname) + ".gz", &ret));
  EXPECT_EQ(0, system((string("rm ") + fname + ".gz").c_str()));
  return ret;
}

vector<char> GenerateSampleMbr() {
  // This is the actual MBR from my dev machine. Partition 1 (the first)
  // is currently marked bootable
  char mbr[512] = {
    0xeb, 0x48, 0x90, 0x10, 0x8e, 0xd0, 0xbc, 0x00,
    0xb0, 0xb8, 0x00, 0x00, 0x8e, 0xd8, 0x8e, 0xc0,
    0xfb, 0xbe, 0x00, 0x7c, 0xbf, 0x00, 0x06, 0xb9,
    0x00, 0x02, 0xf3, 0xa4, 0xea, 0x21, 0x06, 0x00,
    0x00, 0xbe, 0xbe, 0x07, 0x38, 0x04, 0x75, 0x0b,
    0x83, 0xc6, 0x10, 0x81, 0xfe, 0xfe, 0x07, 0x75,
    0xf3, 0xeb, 0x16, 0xb4, 0x02, 0xb0, 0x01, 0xbb,
    0x00, 0x7c, 0xb2, 0x80, 0x8a, 0x74, 0x03, 0x02,
    0xff, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x02, 0xfa, 0x90, 0x90, 0xf6, 0xc2, 0x80,
    0x75, 0x02, 0xb2, 0x80, 0xea, 0x59, 0x7c, 0x00,
    0x00, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xd0, 0xbc,
    0x00, 0x20, 0xfb, 0xa0, 0x40, 0x7c, 0x3c, 0xff,
    0x74, 0x02, 0x88, 0xc2, 0x52, 0xbe, 0x7f, 0x7d,
    0xe8, 0x34, 0x01, 0xf6, 0xc2, 0x80, 0x74, 0x54,
    0xb4, 0x41, 0xbb, 0xaa, 0x55, 0xcd, 0x13, 0x5a,
    0x52, 0x72, 0x49, 0x81, 0xfb, 0x55, 0xaa, 0x75,
    0x43, 0xa0, 0x41, 0x7c, 0x84, 0xc0, 0x75, 0x05,
    0x83, 0xe1, 0x01, 0x74, 0x37, 0x66, 0x8b, 0x4c,
    0x10, 0xbe, 0x05, 0x7c, 0xc6, 0x44, 0xff, 0x01,
    0x66, 0x8b, 0x1e, 0x44, 0x7c, 0xc7, 0x04, 0x10,
    0x00, 0xc7, 0x44, 0x02, 0x01, 0x00, 0x66, 0x89,
    0x5c, 0x08, 0xc7, 0x44, 0x06, 0x00, 0x70, 0x66,
    0x31, 0xc0, 0x89, 0x44, 0x04, 0x66, 0x89, 0x44,
    0x0c, 0xb4, 0x42, 0xcd, 0x13, 0x72, 0x05, 0xbb,
    0x00, 0x70, 0xeb, 0x7d, 0xb4, 0x08, 0xcd, 0x13,
    0x73, 0x0a, 0xf6, 0xc2, 0x80, 0x0f, 0x84, 0xea,
    0x00, 0xe9, 0x8d, 0x00, 0xbe, 0x05, 0x7c, 0xc6,
    0x44, 0xff, 0x00, 0x66, 0x31, 0xc0, 0x88, 0xf0,
    0x40, 0x66, 0x89, 0x44, 0x04, 0x31, 0xd2, 0x88,
    0xca, 0xc1, 0xe2, 0x02, 0x88, 0xe8, 0x88, 0xf4,
    0x40, 0x89, 0x44, 0x08, 0x31, 0xc0, 0x88, 0xd0,
    0xc0, 0xe8, 0x02, 0x66, 0x89, 0x04, 0x66, 0xa1,
    0x44, 0x7c, 0x66, 0x31, 0xd2, 0x66, 0xf7, 0x34,
    0x88, 0x54, 0x0a, 0x66, 0x31, 0xd2, 0x66, 0xf7,
    0x74, 0x04, 0x88, 0x54, 0x0b, 0x89, 0x44, 0x0c,
    0x3b, 0x44, 0x08, 0x7d, 0x3c, 0x8a, 0x54, 0x0d,
    0xc0, 0xe2, 0x06, 0x8a, 0x4c, 0x0a, 0xfe, 0xc1,
    0x08, 0xd1, 0x8a, 0x6c, 0x0c, 0x5a, 0x8a, 0x74,
    0x0b, 0xbb, 0x00, 0x70, 0x8e, 0xc3, 0x31, 0xdb,
    0xb8, 0x01, 0x02, 0xcd, 0x13, 0x72, 0x2a, 0x8c,
    0xc3, 0x8e, 0x06, 0x48, 0x7c, 0x60, 0x1e, 0xb9,
    0x00, 0x01, 0x8e, 0xdb, 0x31, 0xf6, 0x31, 0xff,
    0xfc, 0xf3, 0xa5, 0x1f, 0x61, 0xff, 0x26, 0x42,
    0x7c, 0xbe, 0x85, 0x7d, 0xe8, 0x40, 0x00, 0xeb,
    0x0e, 0xbe, 0x8a, 0x7d, 0xe8, 0x38, 0x00, 0xeb,
    0x06, 0xbe, 0x94, 0x7d, 0xe8, 0x30, 0x00, 0xbe,
    0x99, 0x7d, 0xe8, 0x2a, 0x00, 0xeb, 0xfe, 0x47,
    0x52, 0x55, 0x42, 0x20, 0x00, 0x47, 0x65, 0x6f,
    0x6d, 0x00, 0x48, 0x61, 0x72, 0x64, 0x20, 0x44,
    0x69, 0x73, 0x6b, 0x00, 0x52, 0x65, 0x61, 0x64,
    0x00, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x00,
    0xbb, 0x01, 0x00, 0xb4, 0x0e, 0xcd, 0x10, 0xac,
    0x3c, 0x00, 0x75, 0xf4, 0xc3, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x50, 0xc1, 0x04, 0x00, 0x00, 0x00, 0x80, 0x01,
    0x01, 0x00, 0x83, 0xfe, 0xff, 0xff, 0x3f, 0x00,
    0x00, 0x00, 0x09, 0x7f, 0x32, 0x06, 0x00, 0xfe,
    0xff, 0xff, 0x05, 0xfe, 0xff, 0xff, 0x48, 0x7f,
    0x32, 0x06, 0x79, 0x59, 0x2d, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
  };
  vector<char> ret;
  ret.insert(ret.begin(), mbr, mbr + sizeof(mbr));
  return ret;
}

string BindToUnusedLoopDevice(const string &filename) {
  // get a loop device we can use for the install device
  string cmd = "losetup --show -f " + filename;

  FILE* find_dev_cmd = popen(cmd.c_str(), "r");
  CHECK(find_dev_cmd);

  string ret;
  char dev[100] = {0};
  size_t r;
  while ((r = fread(dev, 1, sizeof(dev - 1), find_dev_cmd)) > 0) {
    EXPECT_LT(r, sizeof(dev));
    ret.insert(ret.end(), dev, dev + r);
  }
  EXPECT_EQ(r, 0);
  EXPECT_TRUE(feof(find_dev_cmd));
  fclose(find_dev_cmd);

  // strip trailing \n on dev
  if (*ret.rbegin() == '\n')
    ret.resize(ret.size() - 1);

  // Ensure that the device starts with "/dev/loop"
  EXPECT_TRUE(StartsWithASCII(ret, "/dev/loop", true));
  return ret;
}

bool ExpectVectorsEq(const vector<char>& expected, const vector<char>& actual) {
  EXPECT_EQ(expected.size(), actual.size());
  if (expected.size() != actual.size())
    return false;
  for (unsigned int i = 0; i < expected.size(); i++) {
    EXPECT_EQ(expected[i], actual[i]) << "offset: " << i;
  }
  return true;
}

void FillWithData(vector<char>* buffer) {
  size_t input_counter = 0;
  for (vector<char>::iterator it = buffer->begin(); it != buffer->end(); ++it) {
    *it = kRandomString[input_counter];
    input_counter++;
    input_counter %= sizeof(kRandomString);
  }
}

void CreateEmptyExtImageAtPath(const string& path,
                               size_t size,
                               int block_size) {
  EXPECT_EQ(0, System(StringPrintf("dd if=/dev/zero of=%s"
                                   " seek=%zu bs=1 count=1",
                                   path.c_str(), size)));
  EXPECT_EQ(0, System(StringPrintf("mkfs.ext3 -b %d -F %s",
                                   block_size, path.c_str())));
}

void CreateExtImageAtPath(const string& path, vector<string>* out_paths) {
  // create 10MiB sparse file
  EXPECT_EQ(0, System(StringPrintf("dd if=/dev/zero of=%s"
                                   " seek=10485759 bs=1 count=1",
                                   path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mkfs.ext3 -b 4096 -F %s", path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mkdir -p %s", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("mount -o loop %s %s", path.c_str(),
                                   kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("echo hi > %s/hi", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("echo hello > %s/hello", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/empty_dir", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/mnt", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("echo T > %s/some_dir/test", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("mkfifo %s/some_dir/fifo", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("mknod %s/cdev c 2 3", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("ln -s /some/target %s/sym", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("ln %s/some_dir/test %s/testlink",
                                   kMountPath, kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("echo T > %s/srchardlink0", kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("ln %s/srchardlink0 %s/srchardlink1",
                                   kMountPath, kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("ln -s bogus %s/boguslink",
                                   kMountPath)));
  EXPECT_EQ(0, System(StringPrintf("umount %s", kMountPath)));

  if (out_paths) {
    out_paths->clear();
    out_paths->push_back("");
    out_paths->push_back("/hi");
    out_paths->push_back("/boguslink");
    out_paths->push_back("/hello");
    out_paths->push_back("/some_dir");
    out_paths->push_back("/some_dir/empty_dir");
    out_paths->push_back("/some_dir/mnt");
    out_paths->push_back("/some_dir/test");
    out_paths->push_back("/some_dir/fifo");
    out_paths->push_back("/cdev");
    out_paths->push_back("/testlink");
    out_paths->push_back("/sym");
    out_paths->push_back("/srchardlink0");
    out_paths->push_back("/srchardlink1");
    out_paths->push_back("/lost+found");
  }
}

void VerifyAllPaths(const string& parent, set<string> expected_paths) {
  FilesystemIterator iter(parent, set<string>());
  ino_t test_ino = 0;
  ino_t testlink_ino = 0;
  while (!iter.IsEnd()) {
    string path = iter.GetFullPath();
    EXPECT_TRUE(expected_paths.find(path) != expected_paths.end()) << path;
    EXPECT_EQ(1, expected_paths.erase(path));
    if (utils::StringHasSuffix(path, "/hi") ||
        utils::StringHasSuffix(path, "/hello") ||
        utils::StringHasSuffix(path, "/test") ||
        utils::StringHasSuffix(path, "/testlink")) {
      EXPECT_TRUE(S_ISREG(iter.GetStat().st_mode));
      if (utils::StringHasSuffix(path, "/test"))
        test_ino = iter.GetStat().st_ino;
      else if (utils::StringHasSuffix(path, "/testlink"))
        testlink_ino = iter.GetStat().st_ino;
    } else if (utils::StringHasSuffix(path, "/some_dir") ||
               utils::StringHasSuffix(path, "/empty_dir") ||
               utils::StringHasSuffix(path, "/mnt") ||
               utils::StringHasSuffix(path, "/lost+found") ||
               parent == path) {
      EXPECT_TRUE(S_ISDIR(iter.GetStat().st_mode));
    } else if (utils::StringHasSuffix(path, "/fifo")) {
      EXPECT_TRUE(S_ISFIFO(iter.GetStat().st_mode));
    } else if (utils::StringHasSuffix(path, "/cdev")) {
      EXPECT_TRUE(S_ISCHR(iter.GetStat().st_mode));
    } else if (utils::StringHasSuffix(path, "/sym")) {
      EXPECT_TRUE(S_ISLNK(iter.GetStat().st_mode));
    } else {
      LOG(INFO) << "got non hardcoded path: " << path;
    }
    iter.Increment();
  }
  EXPECT_EQ(testlink_ino, test_ino);
  EXPECT_NE(0, test_ino);
  EXPECT_FALSE(iter.IsErr());
  EXPECT_TRUE(expected_paths.empty());
  if (!expected_paths.empty()) {
    for (set<string>::const_iterator it = expected_paths.begin();
         it != expected_paths.end(); ++it) {
      LOG(INFO) << "extra path: " << *it;
    }
  }
}

ScopedLoopMounter::ScopedLoopMounter(const string& file_path,
                                     string* mnt_path,
                                     unsigned long flags) {
  EXPECT_TRUE(utils::MakeTempDirectory("/tmp/mnt.XXXXXX", mnt_path));
  dir_remover_.reset(new ScopedDirRemover(*mnt_path));

  string loop_dev;
  loop_binder_.reset(new ScopedLoopbackDeviceBinder(file_path, &loop_dev));

  EXPECT_TRUE(utils::MountFilesystem(loop_dev, *mnt_path, flags));
  unmounter_.reset(new ScopedFilesystemUnmounter(*mnt_path));
}

}  // namespace chromeos_update_engine
