// Copyright 2017 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.
//
// hammerd - A daemon to update the firmware of Hammer

#include <stdlib.h>

#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/stringprintf.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>

#include "hammerd/hammer_updater.h"
#include "hammerd/process_lock.h"
#include "hammerd/usb_utils.h"

namespace {
// The lock file used to prevent multiple hammerd be invoked at the same time.
constexpr char kLockFile[] = "/run/lock/hammerd.lock";

enum class ExitStatus {
  kSuccess                = EXIT_SUCCESS,  // 0
  kUnknownError           = 1,
  kNeedUsbInfo            = 10,
  kEcImageNotFound        = 11,
  kTouchpadImageNotFound  = 12,
  kUnknownUpdateCondition = 13,
  kConnectionError        = 14,
  kInvalidFirmware        = 15,
  kTouchpadMismatched     = 16,
};
}  // namespace

int main(int argc, const char* argv[]) {
  // hammerd should be triggered by upstart job.
  // The default value of arguments are stored in `/etc/init/hammerd.conf`, and
  // each board should override values in `/etc/init/hammerd.override`.
  DEFINE_string(ec_image_path, "", "Path to the EC firmware image file");
  DEFINE_string(touchpad_image_path, "", "Path to the touchpad image file");
  // TODO(b/65534217): Define a flag about touchpad version that is expected
  //                   to be computed by init script.
  DEFINE_int32(vendor_id, -1, "USB vendor ID of the device");
  DEFINE_int32(product_id, -1, "USB product ID of the device");
  DEFINE_int32(usb_bus, -1, "USB bus to search");
  DEFINE_int32(usb_port, -1, "USB port to search");
  DEFINE_int32(autosuspend_delay_ms, -1, "USB autosuspend delay time (ms)");
  DEFINE_bool(at_boot, false,
              "Invoke process at boot time. "
              "Exit if RW is up-to-date (no pairing)");
  DEFINE_string(update_if, "never",
                "Update condition, one of: never|mismatch|always.\n"
                "    never:\n"
                "      Never update, just check if update is needed.\n"
                "    mismatch:\n"
                "      Update as long as the firmware is mismatched.\n"
                "    always:\n"
                "      Update anyways, regardless of version");
  brillo::FlagHelper::Init(argc, argv, "Hammer EC firmware updater daemon");
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogHeader |
                  brillo::kLogToStderrIfTty);

  base::FilePath file_path(kLockFile);
  hammerd::ProcessLock lock(file_path);
  if (!lock.Acquire()) {
    LOG(INFO) << "Other hammerd process is running, exit.";
    return static_cast<int>(ExitStatus::kSuccess);
  }

  if (FLAGS_vendor_id < 0 || FLAGS_product_id < 0 ||
      FLAGS_usb_bus < 0 || FLAGS_usb_port < 0) {
    LOG(ERROR) << "Must specify USB vendor/product ID and bus/port number.";
    return static_cast<int>(ExitStatus::kNeedUsbInfo);
  }

  std::string ec_image;
  if (!base::ReadFileToString(base::FilePath(FLAGS_ec_image_path), &ec_image)) {
    LOG(ERROR) << "EC image file is not found: " << FLAGS_ec_image_path;
    return static_cast<int>(ExitStatus::kEcImageNotFound);
  }

  std::string touchpad_image;
  std::string touchpad_product_id;
  std::string touchpad_fw_ver;
  if (!FLAGS_touchpad_image_path.size()) {
    LOG(INFO) << "Touchpad image is not assigned. " <<
                 "Proceeding without updating touchpad.";

  } else if (!base::ReadFileToString(base::FilePath(FLAGS_touchpad_image_path),
                                     &touchpad_image)) {
    LOG(ERROR) << "Touchpad image is not found with path ["
               << FLAGS_touchpad_image_path << "]. Abort.";
    return static_cast<int>(ExitStatus::kTouchpadImageNotFound);
  } else if (!hammerd::HammerUpdater::ParseTouchpadInfoFromFilename(
        FLAGS_touchpad_image_path, &touchpad_product_id, &touchpad_fw_ver)) {
    LOG(ERROR) << "Not able to get version info from filename. "
               << "Check if [" << FLAGS_touchpad_image_path << "] follows "
               << "<product_id>_<fw_version>.bin format (applied to symbolic "
               << "link as well).";
    return static_cast<int>(ExitStatus::kInvalidFirmware);
  }
  hammerd::HammerUpdater::UpdateCondition update_condition =
      hammerd::HammerUpdater::ToUpdateCondition(FLAGS_update_if);
  if (update_condition == hammerd::HammerUpdater::UpdateCondition::kUnknown) {
    LOG(ERROR) << "Unknown update condition: " << FLAGS_update_if;
    return static_cast<int>(ExitStatus::kUnknownUpdateCondition);
  }

  // The message loop registers a task runner with the current thread, which
  // is used by DBusWrapper to send signals.
  base::MessageLoop message_loop;
  hammerd::HammerUpdater updater(
      ec_image, touchpad_image, touchpad_product_id, touchpad_fw_ver,
      FLAGS_vendor_id, FLAGS_product_id,
      FLAGS_usb_bus, FLAGS_usb_port, FLAGS_at_boot, update_condition);
  hammerd::HammerUpdater::RunStatus ret = updater.Run();
  if (ret == hammerd::HammerUpdater::RunStatus::kNoUpdate &&
      FLAGS_autosuspend_delay_ms >= 0) {
    LOG(INFO) << "Enable USB autosuspend with delay "
              << FLAGS_autosuspend_delay_ms << " ms.";
    base::FilePath base_path =
        hammerd::GetUsbSysfsPath(FLAGS_usb_bus, FLAGS_usb_port);
    constexpr char kPowerLevelPath[] = "power/control";
    constexpr char kAutosuspendDelayMsPath[] = "power/autosuspend_delay_ms";
    constexpr char kPowerLevel[] = "auto";
    std::string delay_ms = base::StringPrintf("%d", FLAGS_autosuspend_delay_ms);

    base::WriteFile(base_path.Append(base::FilePath(kPowerLevelPath)),
                    kPowerLevel, sizeof(kPowerLevel) - 1);
    base::WriteFile(base_path.Append(base::FilePath(kAutosuspendDelayMsPath)),
                    delay_ms.data(), delay_ms.size());
  }
  switch (ret) {
    case hammerd::HammerUpdater::RunStatus::kNoUpdate:
      return static_cast<int>(ExitStatus::kSuccess);
    case hammerd::HammerUpdater::RunStatus::kLostConnection:
    case hammerd::HammerUpdater::RunStatus::kNeedJump:
    case hammerd::HammerUpdater::RunStatus::kNeedReset:
      return static_cast<int>(ExitStatus::kConnectionError);
    case hammerd::HammerUpdater::RunStatus::kInvalidFirmware:
      return static_cast<int>(ExitStatus::kInvalidFirmware);
    case hammerd::HammerUpdater::RunStatus::kTouchpadMismatched:
      return static_cast<int>(ExitStatus::kTouchpadMismatched);
    default:
      return static_cast<int>(ExitStatus::kUnknownError);
  }
}
