// Copyright (c) 2012 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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

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

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

#include "update_engine/file_writer.h"
#include "update_engine/payload_generator/filesystem_iterator.h"
#include "update_engine/utils.h"

using base::StringPrintf;
using std::set;
using std::string;
using std::vector;

namespace chromeos_update_engine {

const char* const kMountPathTemplate = "UpdateEngineTests_mnt-XXXXXX";

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
  unsigned 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(), reinterpret_cast<char *>(mbr),
             reinterpret_cast<char *>(mbr + sizeof(mbr)));
  return ret;
}

// Binds provided |filename| to an unused loopback device, whose name is written
// to the string pointed to by |lo_dev_name_p|. Returns true on success, false
// otherwise (along with corresponding test failures), in which case the content
// of |lo_dev_name_p| is unknown.
bool BindToUnusedLoopDevice(const string& filename, string* lo_dev_name_p) {
  CHECK(lo_dev_name_p);

  // Bind to an unused loopback device, sanity check the device name.
  lo_dev_name_p->clear();
  if (!(utils::ReadPipe("losetup --show -f " + filename, lo_dev_name_p) &&
        StartsWithASCII(*lo_dev_name_p, "/dev/loop", true))) {
    ADD_FAILURE();
    return false;
  }

  // Strip anything from the first newline char.
  size_t newline_pos = lo_dev_name_p->find('\n');
  if (newline_pos != string::npos)
    lo_dev_name_p->erase(newline_pos);

  return true;
}

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

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, mounted at a unique location.
  string mount_path;
  CHECK(utils::MakeTempDirectory(kMountPathTemplate, &mount_path));
  ScopedDirRemover mount_path_unlinker(mount_path);

  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("mount -o loop %s %s", path.c_str(),
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("echo hi > %s/hi", mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("echo hello > %s/hello",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir", mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/empty_dir",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mkdir %s/some_dir/mnt",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("echo T > %s/some_dir/test",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mkfifo %s/some_dir/fifo",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("mknod %s/cdev c 2 3", mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("ln -s /some/target %s/sym",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("ln %s/some_dir/test %s/testlink",
                                   mount_path.c_str(), mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("echo T > %s/srchardlink0",
                                   mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("ln %s/srchardlink0 %s/srchardlink1",
                                   mount_path.c_str(), mount_path.c_str())));
  EXPECT_EQ(0, System(StringPrintf("ln -s bogus %s/boguslink",
                                   mount_path.c_str())));
  EXPECT_TRUE(utils::UnmountFilesystem(mount_path.c_str()));

  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) {  // NOLINT - long
  EXPECT_TRUE(utils::MakeTempDirectory("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));
}

static gboolean RunGMainLoopOnTimeout(gpointer user_data) {
  bool* timeout = static_cast<bool*>(user_data);
  *timeout = true;
  return FALSE;  // Remove timeout source
}

void RunGMainLoopUntil(int timeout_msec, base::Callback<bool()> terminate) {
  GMainLoop* loop = g_main_loop_new(nullptr, FALSE);
  GMainContext* context = g_main_context_default();

  bool timeout = false;
  guint source_id = g_timeout_add(
      timeout_msec, RunGMainLoopOnTimeout, &timeout);

  while (!timeout && (terminate.is_null() || !terminate.Run()))
    g_main_context_iteration(context, TRUE);

  g_source_remove(source_id);
  g_main_loop_unref(loop);
}

int RunGMainLoopMaxIterations(int iterations) {
  int result;
  GMainContext* context = g_main_context_default();
  for (result = 0;
       result < iterations && g_main_context_iteration(context, FALSE);
       result++) {}
  return result;
}

GValue* GValueNewString(const char* str) {
  GValue* gval = g_new0(GValue, 1);
  g_value_init(gval, G_TYPE_STRING);
  g_value_set_string(gval, str);
  return gval;
}

void GValueFree(gpointer arg) {
  auto gval = reinterpret_cast<GValue*>(arg);
  g_value_unset(gval);
  g_free(gval);
}

}  // namespace chromeos_update_engine
