// 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 <errno.h>
#include <fcntl.h>
#include <unistd.h>

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

#include <base/command_line.h>
#include <base/logging.h>
#include <gflags/gflags.h>
#include <glib.h>

#include "update_engine/delta_diff_generator.h"
#include "update_engine/delta_performer.h"
#include "update_engine/prefs.h"
#include "update_engine/subprocess.h"
#include "update_engine/terminator.h"
#include "update_engine/update_metadata.pb.h"
#include "update_engine/utils.h"

DEFINE_string(old_dir, "",
              "Directory where the old rootfs is loop mounted read-only");
DEFINE_string(new_dir, "",
              "Directory where the new rootfs is loop mounted read-only");
DEFINE_string(old_image, "", "Path to the old rootfs");
DEFINE_string(new_image, "", "Path to the new rootfs");
DEFINE_string(out_file, "", "Path to output file");
DEFINE_string(old_kernel, "", "Path to the old kernel partition image");
DEFINE_string(new_kernel, "", "Path to the new kernel partition image");
DEFINE_string(private_key, "", "Path to private key in .pem format");
DEFINE_string(apply_delta, "",
              "If set, apply delta over old_image. (For debugging.)");
DEFINE_string(prefs_dir, "/tmp/update_engine_prefs",
              "Preferences directory, used with apply_delta.");

// This file contains a simple program that takes an old path, a new path,
// and an output file as arguments and the path to an output file and
// generates a delta that can be sent to Chrome OS clients.

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

namespace chromeos_update_engine {

namespace {

bool IsDir(const char* path) {
  struct stat stbuf;
  TEST_AND_RETURN_FALSE_ERRNO(lstat(path, &stbuf) == 0);
  return S_ISDIR(stbuf.st_mode);
}

int Main(int argc, char** argv) {
  g_thread_init(NULL);
  google::ParseCommandLineFlags(&argc, &argv, true);
  CommandLine::Init(argc, argv);
  Terminator::Init();
  Subprocess::Init();
  logging::InitLogging("delta_generator.log",
                       logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
                       logging::DONT_LOCK_LOG_FILE,
                       logging::APPEND_TO_OLD_LOG_FILE);
  if (!FLAGS_apply_delta.empty()) {
    if (FLAGS_old_image.empty()) {
      LOG(FATAL) << "Must pass --old_image with --apply_delta.";
    }
    Prefs prefs;
    LOG(INFO) << "Setting up preferences under: " << FLAGS_prefs_dir;
    LOG_IF(ERROR, !prefs.Init(FilePath(FLAGS_prefs_dir)))
        << "Failed to initialize preferences.";
    // Get original checksums
    LOG(INFO) << "Calculating original checksums";
    PartitionInfo kern_info, root_info;
    CHECK(DeltaDiffGenerator::InitializePartitionInfo(true,  // is_kernel
                                                      FLAGS_old_kernel,
                                                      &kern_info));
    CHECK(DeltaDiffGenerator::InitializePartitionInfo(false,  // is_kernel
                                                      FLAGS_old_image,
                                                      &root_info));
    vector<char> kern_hash(kern_info.hash().begin(),
                           kern_info.hash().end());
    vector<char> root_hash(root_info.hash().begin(),
                           root_info.hash().end());
    DeltaPerformer performer(&prefs);
    performer.set_current_kernel_hash(kern_hash);
    performer.set_current_rootfs_hash(root_hash);
    CHECK_EQ(performer.Open(FLAGS_old_image.c_str(), 0, 0), 0);
    CHECK(performer.OpenKernel(FLAGS_old_kernel.c_str()));
    vector<char> buf(1024 * 1024);
    int fd = open(FLAGS_apply_delta.c_str(), O_RDONLY, 0);
    CHECK_GE(fd, 0);
    ScopedFdCloser fd_closer(&fd);
    for (off_t offset = 0;; offset += buf.size()) {
      ssize_t bytes_read;
      CHECK(utils::PReadAll(fd, &buf[0], buf.size(), offset, &bytes_read));
      if (bytes_read == 0)
        break;
      CHECK_EQ(performer.Write(&buf[0], bytes_read), bytes_read);
    }
    CHECK_EQ(performer.Close(), 0);
    DeltaPerformer::ResetUpdateProgress(&prefs, false);
    LOG(INFO) << "done applying delta.";
    return 0;
  }
  CHECK(!FLAGS_new_image.empty());
  CHECK(!FLAGS_out_file.empty());
  CHECK(!FLAGS_new_kernel.empty());
  if (FLAGS_old_image.empty()) {
    LOG(INFO) << "Generating full update";
  } else {
    LOG(INFO) << "Generating delta update";
    CHECK(!FLAGS_old_dir.empty());
    CHECK(!FLAGS_new_dir.empty());
    if ((!IsDir(FLAGS_old_dir.c_str())) || (!IsDir(FLAGS_new_dir.c_str()))) {
      LOG(FATAL) << "old_dir or new_dir not directory";
    }
  }
  DeltaDiffGenerator::GenerateDeltaUpdateFile(FLAGS_old_dir,
                                              FLAGS_old_image,
                                              FLAGS_new_dir,
                                              FLAGS_new_image,
                                              FLAGS_old_kernel,
                                              FLAGS_new_kernel,
                                              FLAGS_out_file,
                                              FLAGS_private_key);

  return 0;
}

}  // namespace {}

}  // namespace chromeos_update_engine

int main(int argc, char** argv) {
  return chromeos_update_engine::Main(argc, argv);
}
