//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <inttypes.h>
#include <sysexits.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/macros.h>
#include <brillo/daemons/daemon.h>
#include <brillo/flag_helper.h>

#include "update_engine/client.h"
#include "update_engine/common/error_code.h"
#include "update_engine/common/error_code_utils.h"
#include "update_engine/omaha_utils.h"
#include "update_engine/status_update_handler.h"
#include "update_engine/update_status.h"
#include "update_engine/update_status_utils.h"

using chromeos_update_engine::EolStatus;
using chromeos_update_engine::ErrorCode;
using chromeos_update_engine::UpdateStatusToString;
using chromeos_update_engine::utils::ErrorCodeToString;
using std::string;
using std::unique_ptr;
using std::vector;
using update_engine::UpdateStatus;

namespace {

// Constant to signal that we need to continue running the daemon after
// initialization.
const int kContinueRunning = -1;

class UpdateEngineClient : public brillo::Daemon {
 public:
  UpdateEngineClient(int argc, char** argv) : argc_(argc), argv_(argv) {
  }

  ~UpdateEngineClient() override = default;

 protected:
  int OnInit() override {
    int ret = Daemon::OnInit();
    if (ret != EX_OK) return ret;

    client_ = update_engine::UpdateEngineClient::CreateInstance();

    if (!client_) {
      LOG(ERROR) << "UpdateEngineService not available.";
      return 1;
    }

    // We can't call QuitWithExitCode from OnInit(), so we delay the execution
    // of the ProcessFlags method after the Daemon initialization is done.
    base::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&UpdateEngineClient::ProcessFlagsAndExit,
                   base::Unretained(this)));
    return EX_OK;
  }

 private:
  // Show the status of the update engine in stdout.
  bool ShowStatus();

  // Return whether we need to reboot. 0 if reboot is needed, 1 if an error
  // occurred, 2 if no reboot is needed.
  int GetNeedReboot();

  // Main method that parses and triggers all the actions based on the passed
  // flags. Returns the exit code of the program of kContinueRunning if it
  // should not exit.
  int ProcessFlags();

  // Processes the flags and exits the program accordingly.
  void ProcessFlagsAndExit();

  // Copy of argc and argv passed to main().
  int argc_;
  char** argv_;

  // Library-based client
  unique_ptr<update_engine::UpdateEngineClient> client_;

  // Pointers to handlers for cleanup
  vector<unique_ptr<update_engine::StatusUpdateHandler>> handlers_;

  DISALLOW_COPY_AND_ASSIGN(UpdateEngineClient);
};

class ExitingStatusUpdateHandler : public update_engine::StatusUpdateHandler {
 public:
  ~ExitingStatusUpdateHandler() override = default;

  void IPCError(const string& error) override;
};

void ExitingStatusUpdateHandler::IPCError(const string& error) {
  LOG(ERROR) << error;
  exit(1);
}

class WatchingStatusUpdateHandler : public ExitingStatusUpdateHandler {
 public:
  ~WatchingStatusUpdateHandler() override = default;

  void HandleStatusUpdate(int64_t last_checked_time,
                          double progress,
                          UpdateStatus current_operation,
                          const string& new_version,
                          int64_t new_size) override;
};

void WatchingStatusUpdateHandler::HandleStatusUpdate(
    int64_t last_checked_time, double progress, UpdateStatus current_operation,
    const string& new_version, int64_t new_size) {
  LOG(INFO) << "Got status update:";
  LOG(INFO) << "  last_checked_time: " << last_checked_time;
  LOG(INFO) << "  progress: " << progress;
  LOG(INFO) << "  current_operation: "
            << UpdateStatusToString(current_operation);
  LOG(INFO) << "  new_version: " << new_version;
  LOG(INFO) << "  new_size: " << new_size;
}

bool UpdateEngineClient::ShowStatus() {
  int64_t last_checked_time = 0;
  double progress = 0.0;
  UpdateStatus current_op;
  string new_version;
  int64_t new_size = 0;

  if (!client_->GetStatus(&last_checked_time, &progress, &current_op,
                          &new_version, &new_size)) {
    return false;
  }

  printf("LAST_CHECKED_TIME=%" PRIi64
         "\nPROGRESS=%f\nCURRENT_OP=%s\n"
         "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
         last_checked_time, progress, UpdateStatusToString(current_op),
         new_version.c_str(), new_size);

  return true;
}

int UpdateEngineClient::GetNeedReboot() {
  int64_t last_checked_time = 0;
  double progress = 0.0;
  UpdateStatus current_op;
  string new_version;
  int64_t new_size = 0;

  if (!client_->GetStatus(&last_checked_time, &progress, &current_op,
                          &new_version, &new_size)) {
    return 1;
  }

  if (current_op == UpdateStatus::UPDATED_NEED_REBOOT) {
    return 0;
  }

  return 2;
}

class UpdateWaitHandler : public ExitingStatusUpdateHandler {
 public:
  explicit UpdateWaitHandler(bool exit_on_error,
                             update_engine::UpdateEngineClient* client)
      : exit_on_error_(exit_on_error), client_(client) {}

  ~UpdateWaitHandler() override = default;

  void HandleStatusUpdate(int64_t last_checked_time,
                          double progress,
                          UpdateStatus current_operation,
                          const string& new_version,
                          int64_t new_size) override;

 private:
  bool exit_on_error_;
  update_engine::UpdateEngineClient* client_;
};

void UpdateWaitHandler::HandleStatusUpdate(int64_t /* last_checked_time */,
                                           double /* progress */,
                                           UpdateStatus current_operation,
                                           const string& /* new_version */,
                                           int64_t /* new_size */) {
  if (exit_on_error_ && current_operation == UpdateStatus::IDLE) {
    int last_attempt_error;
    ErrorCode code = ErrorCode::kSuccess;
    if (client_ && client_->GetLastAttemptError(&last_attempt_error))
      code = static_cast<ErrorCode>(last_attempt_error);

    LOG(ERROR) << "Update failed, current operation is "
               << UpdateStatusToString(current_operation)
               << ", last error code is " << ErrorCodeToString(code) << "("
               << last_attempt_error << ")";
    exit(1);
  }
  if (current_operation == UpdateStatus::UPDATED_NEED_REBOOT) {
    LOG(INFO) << "Update succeeded -- reboot needed.";
    exit(0);
  }
}

int UpdateEngineClient::ProcessFlags() {
  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_string(
      cohort_hint, "", "Set the current cohort hint to the passed value.");
  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. The device will "
              "be powerwashed unless --nopowerwash is specified.");
  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_cohort_hint, false, "Show the current cohort hint.");
  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(last_attempt_error, false, "Show the last attempt error.");
  DEFINE_bool(eol_status, false, "Show the current end-of-life status.");

  // Boilerplate init commands.
  base::CommandLine::Init(argc_, argv_);
  brillo::FlagHelper::Init(argc_, argv_, "Chromium OS Update Engine Client");

  // Ensure there are no positional arguments.
  const vector<string> positional_args =
      base::CommandLine::ForCurrentProcess()->GetArgs();
  if (!positional_args.empty()) {
    LOG(ERROR) << "Found a positional argument '" << positional_args.front()
               << "'. If you want to pass a value to a flag, pass it as "
                  "--flag=value.";
    return 1;
  }

  // Update the status if requested.
  if (FLAGS_reset_status) {
    LOG(INFO) << "Setting Update Engine status to idle ...";

    if (client_->ResetStatus()) {
      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;)";
    } else {
      LOG(ERROR) << "ResetStatus failed";
      return 1;
    }
  }

  // Changes the current update over cellular network setting.
  if (!FLAGS_update_over_cellular.empty()) {
    bool 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 {
      if (!client_->SetUpdateOverCellularPermission(allowed)) {
        LOG(ERROR) << "Error setting the update over cellular setting.";
        return 1;
      }
    }
  }

  // Show the current update over cellular network setting.
  if (FLAGS_show_update_over_cellular) {
    bool allowed;

    if (!client_->GetUpdateOverCellularPermission(&allowed)) {
      LOG(ERROR) << "Error getting the update over cellular setting.";
      return 1;
    }

    LOG(INFO) << "Current update over cellular network setting: "
              << (allowed ? "ENABLED" : "DISABLED");
  }

  // Change/show the cohort hint.
  bool set_cohort_hint =
      base::CommandLine::ForCurrentProcess()->HasSwitch("cohort_hint");
  if (set_cohort_hint) {
    LOG(INFO) << "Setting cohort hint to: \"" << FLAGS_cohort_hint << "\"";
    if (!client_->SetCohortHint(FLAGS_cohort_hint)) {
      LOG(ERROR) << "Error setting the cohort hint.";
      return 1;
    }
  }

  if (FLAGS_show_cohort_hint || set_cohort_hint) {
    string cohort_hint;
    if (!client_->GetCohortHint(&cohort_hint)) {
      LOG(ERROR) << "Error getting the cohort hint.";
      return 1;
    }

    LOG(INFO) << "Current cohort hint: \"" << cohort_hint << "\"";
  }

  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()) {
    bool enabled = FLAGS_p2p_update == "yes";
    if (!enabled && FLAGS_p2p_update != "no") {
      LOG(ERROR) << "Unknown option: \"" << FLAGS_p2p_update
                 << "\". Please specify \"yes\" or \"no\".";
    } else {
      if (!client_->SetP2PUpdatePermission(enabled)) {
        LOG(ERROR) << "Error setting the peer-to-peer update setting.";
        return 1;
      }
    }
  }

  // Show the rollback availability.
  if (FLAGS_can_rollback) {
    string rollback_partition;

    if (!client_->GetRollbackPartition(&rollback_partition)) {
      LOG(ERROR) << "Error while querying rollback partition availabilty.";
      return 1;
    }

    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;

    if (!client_->GetP2PUpdatePermission(&enabled)) {
      LOG(ERROR) << "Error getting the peer-to-peer update setting.";
      return 1;
    }

    LOG(INFO) << "Current update using P2P setting: "
              << (enabled ? "ENABLED" : "DISABLED");
  }

  // First, update the target channel if requested.
  if (!FLAGS_channel.empty()) {
    if (!client_->SetTargetChannel(FLAGS_channel, FLAGS_powerwash)) {
      LOG(ERROR) << "Error setting the channel.";
      return 1;
    }

    LOG(INFO) << "Channel permanently set to: " << FLAGS_channel;
  }

  // Show the current and target channels if requested.
  if (FLAGS_show_channel) {
    string current_channel;
    string target_channel;

    if (!client_->GetChannel(&current_channel)) {
      LOG(ERROR) << "Error getting the current channel.";
      return 1;
    }

    if (!client_->GetTargetChannel(&target_channel)) {
      LOG(ERROR) << "Error getting the target channel.";
      return 1;
    }

    LOG(INFO) << "Current Channel: " << current_channel;

    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.";
    if (!client_->Rollback(FLAGS_powerwash)) {
      LOG(ERROR) << "Rollback request failed.";
      return 1;
    }
  }

  // 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.";
    if (!client_->AttemptUpdate(app_version, FLAGS_omaha_url,
                                FLAGS_interactive)) {
      LOG(ERROR) << "Error checking for update.";
      return 1;
    }
  }

  // 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 (!ShowStatus()) {
      LOG(ERROR) << "Failed to query status";
      return 1;
    }
    return 0;
  }

  if (FLAGS_follow) {
    LOG(INFO) << "Waiting for update to complete.";
    auto handler = new UpdateWaitHandler(true, client_.get());
    handlers_.emplace_back(handler);
    client_->RegisterStatusUpdateHandler(handler);
    return kContinueRunning;
  }

  if (FLAGS_watch_for_updates) {
    LOG(INFO) << "Watching for status updates.";
    auto handler = new WatchingStatusUpdateHandler();
    handlers_.emplace_back(handler);
    client_->RegisterStatusUpdateHandler(handler);
    return kContinueRunning;
  }

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

  if (FLAGS_prev_version) {
    string prev_version;

    if (!client_->GetPrevVersion(&prev_version)) {
      LOG(ERROR) << "Error getting previous version.";
    } else {
      LOG(INFO) << "Previous version = " << prev_version;
    }
  }

  if (FLAGS_is_reboot_needed) {
    int ret = GetNeedReboot();

    if (ret == 1) {
      LOG(ERROR) << "Could not query the current operation.";
    }

    return ret;
  }

  if (FLAGS_block_until_reboot_is_needed) {
    auto handler = new UpdateWaitHandler(false, nullptr);
    handlers_.emplace_back(handler);
    client_->RegisterStatusUpdateHandler(handler);
    return kContinueRunning;
  }

  if (FLAGS_last_attempt_error) {
    int last_attempt_error;
    if (!client_->GetLastAttemptError(&last_attempt_error)) {
      LOG(ERROR) << "Error getting last attempt error.";
    } else {
      ErrorCode code = static_cast<ErrorCode>(last_attempt_error);
      printf(
          "ERROR_CODE=%i\n"
          "ERROR_MESSAGE=%s\n",
          last_attempt_error,
          ErrorCodeToString(code).c_str());
    }
  }

  if (FLAGS_eol_status) {
    int eol_status;
    if (!client_->GetEolStatus(&eol_status)) {
      LOG(ERROR) << "Error getting the end-of-life status.";
    } else {
      EolStatus eol_status_code = static_cast<EolStatus>(eol_status);
      printf("EOL_STATUS=%s\n", EolStatusToString(eol_status_code));
    }
  }

  return 0;
}

void UpdateEngineClient::ProcessFlagsAndExit() {
  int ret = ProcessFlags();
  if (ret != kContinueRunning)
    QuitWithExitCode(ret);
}

}  // namespace

int main(int argc, char** argv) {
  UpdateEngineClient client(argc, argv);
  return client.Run();
}
