// 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 <string>

#include <base/logging.h>
#include <chromeos/dbus/service_constants.h>
#include <chromeos/flag_helper.h>
#include <dbus/dbus.h>
#include <glib.h>
#include <inttypes.h>

#include "update_engine/dbus_constants.h"
#include "update_engine/glib_utils.h"

extern "C" {
#include "update_engine/update_engine.dbusclient.h"
}

using chromeos_update_engine::AttemptUpdateFlags;
using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
using chromeos_update_engine::kUpdateEngineServiceInterface;
using chromeos_update_engine::kUpdateEngineServiceName;
using chromeos_update_engine::kUpdateEngineServicePath;
using chromeos_update_engine::utils::GetAndFreeGError;
using std::string;

namespace {

bool GetProxy(DBusGProxy** out_proxy) {
  DBusGConnection* bus;
  DBusGProxy* proxy = nullptr;
  GError* error = nullptr;
  const int kTries = 4;
  const int kRetrySeconds = 10;

  bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
  if (bus == nullptr) {
    LOG(ERROR) << "Failed to get bus: " << GetAndFreeGError(&error);
    exit(1);
  }
  for (int i = 0; !proxy && i < kTries; ++i) {
    if (i > 0) {
      LOG(INFO) << "Retrying to get dbus proxy. Try "
                << (i + 1) << "/" << kTries;
      g_usleep(kRetrySeconds * G_USEC_PER_SEC);
    }
    proxy = dbus_g_proxy_new_for_name_owner(bus,
                                            kUpdateEngineServiceName,
                                            kUpdateEngineServicePath,
                                            kUpdateEngineServiceInterface,
                                            &error);
    LOG_IF(WARNING, !proxy) << "Error getting dbus proxy for "
                            << kUpdateEngineServiceName << ": "
                            << GetAndFreeGError(&error);
  }
  if (proxy == nullptr) {
    LOG(ERROR) << "Giving up -- unable to get dbus proxy for "
               << kUpdateEngineServiceName;
    exit(1);
  }
  *out_proxy = proxy;
  return true;
}

static void StatusUpdateSignalHandler(DBusGProxy* proxy,
                                      int64_t last_checked_time,
                                      double progress,
                                      gchar* current_operation,
                                      gchar* new_version,
                                      int64_t new_size,
                                      void* user_data) {
  LOG(INFO) << "Got status update:";
  LOG(INFO) << "  last_checked_time: " << last_checked_time;
  LOG(INFO) << "  progress: " << progress;
  LOG(INFO) << "  current_operation: " << current_operation;
  LOG(INFO) << "  new_version: " << new_version;
  LOG(INFO) << "  new_size: " << new_size;
}

bool ResetStatus() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean rc = update_engine_client_reset_status(proxy, &error);
  return rc;
}


// If |op| is non-null, sets it to the current operation string or an
// empty string if unable to obtain the current status.
bool GetStatus(string* op) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gint64 last_checked_time = 0;
  gdouble progress = 0.0;
  char* current_op = nullptr;
  char* new_version = nullptr;
  gint64 new_size = 0;

  gboolean rc = update_engine_client_get_status(proxy,
                                                &last_checked_time,
                                                &progress,
                                                &current_op,
                                                &new_version,
                                                &new_size,
                                                &error);
  if (rc == FALSE) {
    LOG(INFO) << "Error getting status: " << GetAndFreeGError(&error);
  }
  printf("LAST_CHECKED_TIME=%" PRIi64 "\nPROGRESS=%f\nCURRENT_OP=%s\n"
         "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
         last_checked_time,
         progress,
         current_op,
         new_version,
         new_size);
  if (op) {
    *op = current_op ? current_op : "";
  }
  return true;
}

// Should never return.
void WatchForUpdates() {
  DBusGProxy* proxy;

  CHECK(GetProxy(&proxy));

  // Register marshaller
  dbus_g_object_register_marshaller(
      g_cclosure_marshal_generic,
      G_TYPE_NONE,
      G_TYPE_INT64,
      G_TYPE_DOUBLE,
      G_TYPE_STRING,
      G_TYPE_STRING,
      G_TYPE_INT64,
      G_TYPE_INVALID);

  static const char kStatusUpdate[] = "StatusUpdate";
  dbus_g_proxy_add_signal(proxy,
                          kStatusUpdate,
                          G_TYPE_INT64,
                          G_TYPE_DOUBLE,
                          G_TYPE_STRING,
                          G_TYPE_STRING,
                          G_TYPE_INT64,
                          G_TYPE_INVALID);
  GMainLoop* loop = g_main_loop_new(nullptr, TRUE);
  dbus_g_proxy_connect_signal(proxy,
                              kStatusUpdate,
                              G_CALLBACK(StatusUpdateSignalHandler),
                              nullptr,
                              nullptr);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

bool Rollback(bool rollback) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean rc = update_engine_client_attempt_rollback(proxy,
                                                      rollback,
                                                      &error);
  CHECK_EQ(rc, TRUE) << "Error with rollback request: "
                     << GetAndFreeGError(&error);
  return true;
}

std::string GetRollbackPartition() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  char* rollback_partition = nullptr;
  gboolean rc = update_engine_client_get_rollback_partition(proxy,
                                                            &rollback_partition,
                                                            &error);
  CHECK_EQ(rc, TRUE) << "Error while querying rollback partition availabilty: "
                     << GetAndFreeGError(&error);
  std::string partition = rollback_partition;
  g_free(rollback_partition);
  return partition;
}

std::string GetKernelDevices() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  char* kernel_devices = nullptr;
  gboolean rc = update_engine_client_get_kernel_devices(proxy,
                                                        &kernel_devices,
                                                        &error);
  CHECK_EQ(rc, TRUE) << "Error while getting a list of kernel devices: "
    << GetAndFreeGError(&error);
  std::string devices = kernel_devices;
  g_free(kernel_devices);
  return devices;
}

bool CheckForUpdates(const string& app_version,
                     const string& omaha_url,
                     bool interactive) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(
      interactive ? 0 : kAttemptUpdateFlagNonInteractive);
  gboolean rc =
      update_engine_client_attempt_update_with_flags(proxy,
                                                     app_version.c_str(),
                                                     omaha_url.c_str(),
                                                     static_cast<gint>(flags),
                                                     &error);
  CHECK_EQ(rc, TRUE) << "Error checking for update: "
                     << GetAndFreeGError(&error);
  return true;
}

bool RebootIfNeeded() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      update_engine_client_reboot_if_needed(proxy, &error);
  // Reboot error code doesn't necessarily mean that a reboot
  // failed. For example, D-Bus may be shutdown before we receive the
  // result.
  LOG_IF(INFO, !rc) << "Reboot error message: " << GetAndFreeGError(&error);
  return true;
}

void SetTargetChannel(const string& target_channel, bool allow_powerwash) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean rc = update_engine_client_set_channel(proxy,
                                                 target_channel.c_str(),
                                                 allow_powerwash,
                                                 &error);
  CHECK_EQ(rc, true) << "Error setting the channel: "
                     << GetAndFreeGError(&error);
  LOG(INFO) << "Channel permanently set to: " << target_channel;
}

string GetChannel(bool get_current_channel) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  char* channel = nullptr;
  gboolean rc = update_engine_client_get_channel(proxy,
                                                 get_current_channel,
                                                 &channel,
                                                 &error);
  CHECK_EQ(rc, true) << "Error getting the channel: "
                     << GetAndFreeGError(&error);
  string output = channel;
  g_free(channel);
  return output;
}

void SetUpdateOverCellularPermission(gboolean allowed) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean rc = update_engine_client_set_update_over_cellular_permission(
      proxy,
      allowed,
      &error);
  CHECK_EQ(rc, true) << "Error setting the update over cellular setting: "
                     << GetAndFreeGError(&error);
}

bool GetUpdateOverCellularPermission() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean allowed;
  gboolean rc = update_engine_client_get_update_over_cellular_permission(
      proxy,
      &allowed,
      &error);
  CHECK_EQ(rc, true) << "Error getting the update over cellular setting: "
                     << GetAndFreeGError(&error);
  return allowed;
}

void SetP2PUpdatePermission(gboolean enabled) {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean rc = update_engine_client_set_p2p_update_permission(
      proxy,
      enabled,
      &error);
  CHECK_EQ(rc, true) << "Error setting the peer-to-peer update setting: "
                     << GetAndFreeGError(&error);
}

bool GetP2PUpdatePermission() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  gboolean enabled;
  gboolean rc = update_engine_client_get_p2p_update_permission(
      proxy,
      &enabled,
      &error);
  CHECK_EQ(rc, true) << "Error getting the peer-to-peer update setting: "
                     << GetAndFreeGError(&error);
  return enabled;
}

static gboolean CompleteUpdateSource(gpointer data) {
  string current_op;
  if (!GetStatus(&current_op) || current_op == "UPDATE_STATUS_IDLE") {
    LOG(ERROR) << "Update failed.";
    exit(1);
  }
  if (current_op == "UPDATE_STATUS_UPDATED_NEED_REBOOT") {
    LOG(INFO) << "Update succeeded -- reboot needed.";
    exit(0);
  }
  return TRUE;
}

// This is similar to watching for updates but rather than registering
// a signal watch, actively poll the daemon just in case it stops
// sending notifications.
void CompleteUpdate() {
  GMainLoop* loop = g_main_loop_new(nullptr, TRUE);
  g_timeout_add_seconds(5, CompleteUpdateSource, nullptr);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

void ShowPrevVersion() {
  DBusGProxy* proxy;
  GError* error = nullptr;

  CHECK(GetProxy(&proxy));

  char* prev_version = nullptr;

  gboolean rc = update_engine_client_get_prev_version(proxy,
                                                      &prev_version,
                                                      &error);
  if (!rc) {
    LOG(ERROR) << "Error getting previous version: "
               << GetAndFreeGError(&error);
  } else {
    LOG(INFO) << "Previous version = " << prev_version;
    g_free(prev_version);
  }
}

bool CheckIfRebootIsNeeded(DBusGProxy *proxy, bool *out_reboot_needed) {
  gint64 last_checked_time = 0;
  gdouble progress = 0.0;
  char* current_op = nullptr;
  char* new_version = nullptr;
  gint64 new_size = 0;
  GError* error = nullptr;

  if (!update_engine_client_get_status(proxy,
                                       &last_checked_time,
                                       &progress,
                                       &current_op,
                                       &new_version,
                                       &new_size,
                                       &error)) {
    LOG(INFO) << "Error getting status: " << GetAndFreeGError(&error);
    return false;
  }
  *out_reboot_needed =
      (g_strcmp0(current_op,
                 update_engine::kUpdateStatusUpdatedNeedReboot) == 0);
  g_free(current_op);
  g_free(new_version);
  return true;
}

// Determines if reboot is needed. The result is returned in
// |out_reboot_needed|. Returns true if the check succeeded, false
// otherwise.
bool IsRebootNeeded(bool *out_reboot_needed) {
  DBusGProxy* proxy = nullptr;
  CHECK(GetProxy(&proxy));
  bool ret = CheckIfRebootIsNeeded(proxy, out_reboot_needed);
  g_object_unref(proxy);
  return ret;
}

static void OnBlockUntilRebootStatusCallback(
    DBusGProxy* proxy,
    int64_t last_checked_time,
    double progress,
    const gchar* current_operation,
    const gchar* new_version,
    int64_t new_size,
    void* user_data) {
  GMainLoop *loop = reinterpret_cast<GMainLoop*>(user_data);
  if (g_strcmp0(current_operation,
                update_engine::kUpdateStatusUpdatedNeedReboot) == 0) {
    g_main_loop_quit(loop);
  }
}

bool CheckRebootNeeded(DBusGProxy *proxy, GMainLoop *loop) {
  bool reboot_needed;
  if (!CheckIfRebootIsNeeded(proxy, &reboot_needed))
    return false;
  if (reboot_needed)
    return true;
  // This will block until OnBlockUntilRebootStatusCallback() calls
  // g_main_loop_quit().
  g_main_loop_run(loop);
  return true;
}

// Blocks until a reboot is needed. Returns true if waiting succeeded,
// false if an error occurred.
bool BlockUntilRebootIsNeeded() {
  // The basic idea is to get a proxy, listen to signals and only then
  // check the status. If no reboot is needed, just sit and wait for
  // the StatusUpdate signal to convey that a reboot is pending.
  DBusGProxy* proxy = nullptr;
  CHECK(GetProxy(&proxy));
  dbus_g_object_register_marshaller(
      g_cclosure_marshal_generic,
      G_TYPE_NONE,
      G_TYPE_INT64,
      G_TYPE_DOUBLE,
      G_TYPE_STRING,
      G_TYPE_STRING,
      G_TYPE_INT64,
      G_TYPE_INVALID);
  dbus_g_proxy_add_signal(proxy,
                          update_engine::kStatusUpdate,  // Signal name.
                          G_TYPE_INT64,
                          G_TYPE_DOUBLE,
                          G_TYPE_STRING,
                          G_TYPE_STRING,
                          G_TYPE_INT64,
                          G_TYPE_INVALID);
  GMainLoop* loop = g_main_loop_new(nullptr, TRUE);
  dbus_g_proxy_connect_signal(proxy,
                              update_engine::kStatusUpdate,
                              G_CALLBACK(OnBlockUntilRebootStatusCallback),
                              loop,
                              nullptr);  // free_data_func.

  bool ret = CheckRebootNeeded(proxy, loop);

  dbus_g_proxy_disconnect_signal(proxy,
                                 update_engine::kStatusUpdate,
                                 G_CALLBACK(OnBlockUntilRebootStatusCallback),
                                 loop);
  g_main_loop_unref(loop);
  g_object_unref(proxy);
  return ret;
}

}  // namespace

int main(int argc, char** argv) {
  DEFINE_string(app_version, "", "Force the current app version.");
  DEFINE_string(channel, "",
                "Set the target channel. The device will be powerwashed if the "
                "target channel is more stable than the current channel unless "
                "--nopowerwash is specified.");
  DEFINE_bool(check_for_update, false, "Initiate check for updates.");
  DEFINE_bool(follow, false, "Wait for any update operations to complete."
              "Exit status is 0 if the update succeeded, and 1 otherwise.");
  DEFINE_bool(interactive, true, "Mark the update request as interactive.");
  DEFINE_string(omaha_url, "", "The URL of the Omaha update server.");
  DEFINE_string(p2p_update, "",
                "Enables (\"yes\") or disables (\"no\") the peer-to-peer update"
                " sharing.");
  DEFINE_bool(powerwash, true, "When performing rollback or channel change, "
              "do a powerwash or allow it respectively.");
  DEFINE_bool(reboot, false, "Initiate a reboot if needed.");
  DEFINE_bool(is_reboot_needed, false, "Exit status 0 if reboot is needed, "
              "2 if reboot is not needed or 1 if an error occurred.");
  DEFINE_bool(block_until_reboot_is_needed, false, "Blocks until reboot is "
              "needed. Returns non-zero exit status if an error occurred.");
  DEFINE_bool(reset_status, false, "Sets the status in update_engine to idle.");
  DEFINE_bool(rollback, false, "Perform a rollback to the previous partition.");
  DEFINE_bool(can_rollback, false, "Shows whether rollback partition "
              "is available.");
  DEFINE_bool(show_channel, false, "Show the current and target channels.");
  DEFINE_bool(show_p2p_update, false,
              "Show the current setting for peer-to-peer update sharing.");
  DEFINE_bool(show_update_over_cellular, false,
              "Show the current setting for updates over cellular networks.");
  DEFINE_bool(status, false, "Print the status to stdout.");
  DEFINE_bool(update, false, "Forces an update and waits for it to complete. "
              "Implies --follow.");
  DEFINE_string(update_over_cellular, "",
                "Enables (\"yes\") or disables (\"no\") the updates over "
                "cellular networks.");
  DEFINE_bool(watch_for_updates, false,
              "Listen for status updates and print them to the screen.");
  DEFINE_bool(prev_version, false,
              "Show the previous OS version used before the update reboot.");
  DEFINE_bool(show_kernels, false, "Show the list of kernel patritions and "
              "whether each of them is bootable or not");

  // Boilerplate init commands.
  g_type_init();
  dbus_threads_init_default();
  chromeos::FlagHelper::Init(argc, argv, "Chromium OS Update Engine Client");

  // Update the status if requested.
  if (FLAGS_reset_status) {
    LOG(INFO) << "Setting Update Engine status to idle ...";
    if (!ResetStatus()) {
      LOG(ERROR) << "ResetStatus failed.";
      return 1;
    }
    LOG(INFO) << "ResetStatus succeeded; to undo partition table changes run:\n"
                 "(D=$(rootdev -d) P=$(rootdev -s); cgpt p -i$(($(echo ${P#$D} "
                 "| sed 's/^[^0-9]*//')-1)) $D;)";
  }

  // Changes the current update over cellular network setting.
  if (!FLAGS_update_over_cellular.empty()) {
    gboolean allowed = FLAGS_update_over_cellular == "yes";
    if (!allowed && FLAGS_update_over_cellular != "no") {
      LOG(ERROR) << "Unknown option: \"" << FLAGS_update_over_cellular
                 << "\". Please specify \"yes\" or \"no\".";
    } else {
      SetUpdateOverCellularPermission(allowed);
    }
  }

  // Show the current update over cellular network setting.
  if (FLAGS_show_update_over_cellular) {
    bool allowed = GetUpdateOverCellularPermission();
    LOG(INFO) << "Current update over cellular network setting: "
              << (allowed ? "ENABLED" : "DISABLED");
  }

  if (!FLAGS_powerwash && !FLAGS_rollback && FLAGS_channel.empty()) {
    LOG(ERROR) << "powerwash flag only makes sense rollback or channel change";
    return 1;
  }

  // Change the P2P enabled setting.
  if (!FLAGS_p2p_update.empty()) {
    gboolean enabled = FLAGS_p2p_update == "yes";
    if (!enabled && FLAGS_p2p_update != "no") {
      LOG(ERROR) << "Unknown option: \"" << FLAGS_p2p_update
                 << "\". Please specify \"yes\" or \"no\".";
    } else {
      SetP2PUpdatePermission(enabled);
    }
  }

  // Show the rollback availability.
  if (FLAGS_can_rollback) {
    std::string rollback_partition = GetRollbackPartition();
    bool can_rollback = true;
    if (rollback_partition.empty()) {
      rollback_partition = "UNAVAILABLE";
      can_rollback = false;
    } else {
      rollback_partition = "AVAILABLE: " + rollback_partition;
    }

    LOG(INFO) << "Rollback partition: " << rollback_partition;
    if (!can_rollback) {
      return 1;
    }
  }

  // Show the current P2P enabled setting.
  if (FLAGS_show_p2p_update) {
    bool enabled = GetP2PUpdatePermission();
    LOG(INFO) << "Current update using P2P setting: "
              << (enabled ? "ENABLED" : "DISABLED");
  }

  // First, update the target channel if requested.
  if (!FLAGS_channel.empty())
    SetTargetChannel(FLAGS_channel, FLAGS_powerwash);

  // Show the current and target channels if requested.
  if (FLAGS_show_channel) {
    string current_channel = GetChannel(true);
    LOG(INFO) << "Current Channel: " << current_channel;

    string target_channel = GetChannel(false);
    if (!target_channel.empty())
      LOG(INFO) << "Target Channel (pending update): " << target_channel;
  }

  bool do_update_request = FLAGS_check_for_update | FLAGS_update |
      !FLAGS_app_version.empty() | !FLAGS_omaha_url.empty();
  if (FLAGS_update)
    FLAGS_follow = true;

  if (do_update_request && FLAGS_rollback) {
    LOG(ERROR) << "Incompatible flags specified with rollback."
               << "Rollback should not include update-related flags.";
    return 1;
  }

  if (FLAGS_rollback) {
    LOG(INFO) << "Requesting rollback.";
    CHECK(Rollback(FLAGS_powerwash)) << "Request for rollback failed.";
  }

  // Initiate an update check, if necessary.
  if (do_update_request) {
    LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
    string app_version = FLAGS_app_version;
    if (FLAGS_update && app_version.empty()) {
      app_version = "ForcedUpdate";
      LOG(INFO) << "Forcing an update by setting app_version to ForcedUpdate.";
    }
    LOG(INFO) << "Initiating update check and install.";
    CHECK(CheckForUpdates(app_version, FLAGS_omaha_url, FLAGS_interactive))
        << "Update check/initiate update failed.";
  }

  // These final options are all mutually exclusive with one another.
  if (FLAGS_follow + FLAGS_watch_for_updates + FLAGS_reboot +
      FLAGS_status + FLAGS_is_reboot_needed +
      FLAGS_block_until_reboot_is_needed > 1) {
    LOG(ERROR) << "Multiple exclusive options selected. "
               << "Select only one of --follow, --watch_for_updates, --reboot, "
               << "--is_reboot_needed, --block_until_reboot_is_needed, "
               << "or --status.";
    return 1;
  }

  if (FLAGS_status) {
    LOG(INFO) << "Querying Update Engine status...";
    if (!GetStatus(nullptr)) {
      LOG(ERROR) << "GetStatus failed.";
      return 1;
    }
    return 0;
  }

  if (FLAGS_follow) {
    LOG(INFO) << "Waiting for update to complete.";
    CompleteUpdate();  // Should never return.
    return 1;
  }

  if (FLAGS_watch_for_updates) {
    LOG(INFO) << "Watching for status updates.";
    WatchForUpdates();  // Should never return.
    return 1;
  }

  if (FLAGS_reboot) {
    LOG(INFO) << "Requesting a reboot...";
    CHECK(RebootIfNeeded());
    return 0;
  }

  if (FLAGS_prev_version) {
    ShowPrevVersion();
  }

  if (FLAGS_show_kernels) {
    LOG(INFO) << "Kernel partitions:\n"
              << GetKernelDevices();
  }

  if (FLAGS_is_reboot_needed) {
    bool reboot_needed = false;
    if (!IsRebootNeeded(&reboot_needed))
      return 1;
    else if (!reboot_needed)
      return 2;
  }

  if (FLAGS_block_until_reboot_is_needed) {
    if (!BlockUntilRebootIsNeeded())
      return 1;
  }

  LOG(INFO) << "Done.";
  return 0;
}
