// 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 "hammerd/hammer_updater.h"

#include <unistd.h>

#include <pcrecpp.h>

#include <memory>
#include <string>
#include <utility>

#include <base/check.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>
#include <chromeos/dbus/service_constants.h>

#include "hammerd/uma_metric_names.h"

namespace hammerd {

const std::string HammerUpdater::TaskState::ToString() {
  return base::StringPrintf(
      "update_ro(%d) update_rw(%d) update_tp(%d) "
      "inject_entropy(%d) post_rw_jump(%d)",
      update_ro, update_rw, update_tp, inject_entropy, post_rw_jump);
}

HammerUpdater::UpdateCondition HammerUpdater::ToUpdateCondition(
    const std::string& s) {
  if (s == "never")
    return UpdateCondition::kNever;
  if (s == "mismatch")
    return UpdateCondition::kMismatch;
  if (s == "always")
    return UpdateCondition::kAlways;
  return UpdateCondition::kUnknown;
}

HammerUpdater::HammerUpdater(const std::string& ec_image,
                             const std::string& touchpad_image,
                             const std::string& touchpad_product_id,
                             const std::string& touchpad_fw_ver,
                             uint16_t vendor_id,
                             uint16_t product_id,
                             const std::string& usb_path,
                             bool at_boot,
                             UpdateCondition update_condition)
    : HammerUpdater(
          ec_image,
          touchpad_image,
          touchpad_product_id,
          touchpad_fw_ver,
          usb_path,
          at_boot,
          update_condition,
          std::make_unique<FirmwareUpdater>(
              std::make_unique<UsbEndpoint>(vendor_id, product_id, usb_path)),
          std::make_unique<PairManager>(),
          std::make_unique<DBusWrapper>(),
          std::make_unique<MetricsLibrary>()) {}

HammerUpdater::HammerUpdater(
    const std::string& ec_image,
    const std::string& touchpad_image,
    const std::string& touchpad_product_id,
    const std::string& touchpad_fw_ver,
    const std::string& usb_path,
    bool at_boot,
    UpdateCondition update_condition,
    std::unique_ptr<FirmwareUpdaterInterface> fw_updater,
    std::unique_ptr<PairManagerInterface> pair_manager,
    std::unique_ptr<DBusWrapperInterface> dbus_wrapper,
    std::unique_ptr<MetricsLibraryInterface> metrics)
    : ec_image_(ec_image),
      touchpad_image_(touchpad_image),
      touchpad_product_id_(touchpad_product_id),
      touchpad_fw_ver_(touchpad_fw_ver),
      usb_path_(usb_path),
      at_boot_(at_boot),
      update_condition_(update_condition),
      task_(HammerUpdater::TaskState()),
      fw_updater_(std::move(fw_updater)),
      pair_manager_(std::move(pair_manager)),
      dbus_wrapper_(std::move(dbus_wrapper)),
      dbus_notified_(false),
      metrics_(std::move(metrics)) {}

HammerUpdater::RunStatus HammerUpdater::Run() {
  LOG(INFO) << "Load and validate the EC image.";
  if (!fw_updater_->LoadEcImage(ec_image_)) {
    LOG(ERROR) << "Failed to load EC image.";
    return HammerUpdater::RunStatus::kInvalidFirmware;
  }

  HammerUpdater::RunStatus status = RunLoop();
  WaitUsbReady(status);
  if (update_condition_ != UpdateCondition::kNever) {
    NotifyUpdateFinished(status == HammerUpdater::RunStatus::kNoUpdate);
  }
  return status;
}

HammerUpdater::RunStatus HammerUpdater::UpdateRW() {
  bool ret = fw_updater_->TransferImage(SectionName::RW);
  task_.update_rw = !ret;
  metrics_->SendEnumToUMA(
      kMetricRWUpdateResult,
      static_cast<int>(ret ? RWUpdateResult::kSucceeded
                           : RWUpdateResult::kTransferFailed),
      static_cast<int>(RWUpdateResult::kCount));
  LOG(INFO) << "RW update " << (ret ? "passed." : "failed.");
  return HammerUpdater::RunStatus::kNeedReset;
}

HammerUpdater::RunStatus HammerUpdater::RunLoop() {
  constexpr unsigned int kMaximumRunCount = 20;
  // Time it takes hammer to reset or jump to RW, before being
  // available for the next USB connection.
  constexpr unsigned int kResetTimeMs = 200;
  bool criticality_checked = false;
  bool can_update = update_condition_ != UpdateCondition::kNever;
  bool invalid_device_seen = false;
  // Set all update flags if update mode is forced.
  if (update_condition_ == UpdateCondition::kAlways) {
    task_.update_ro = true;
    task_.update_rw = true;
    task_.update_tp = true;
  }

  HammerUpdater::RunStatus status;
  for (int run_count = 0; run_count < kMaximumRunCount; ++run_count) {
    UsbConnectStatus connect_status = fw_updater_->TryConnectUsb();
    if (connect_status != UsbConnectStatus::kSuccess) {
      // If this is the first InvalidDevice error and not the last
      // iteration, try to reboot the device back to RO and give it
      // a second chance.
      if (connect_status == UsbConnectStatus::kInvalidDevice &&
          !invalid_device_seen && run_count != kMaximumRunCount - 1) {
        LOG(INFO) << "Device with invalid ID found, try to reboot to RO.";
        invalid_device_seen = true;
        // Create an updater instance that allows any usb ID.
        FirmwareUpdater fw_updater(std::make_unique<UsbEndpoint>(usb_path_));
        if (fw_updater.TryConnectUsb() == UsbConnectStatus::kSuccess) {
          fw_updater.SendSubcommand(UpdateExtraCommand::kImmediateReset);
          fw_updater.CloseUsb();
          base::PlatformThread::Sleep(
              base::TimeDelta::FromMilliseconds(kResetTimeMs));
        }
        status = HammerUpdater::RunStatus::kNeedJump;
        continue;
      }

      if (!criticality_checked && !can_update) {
        metrics_->SendEnumToUMA(
            kMetricPendingRWUpdate,
            static_cast<int>(PendingRWUpdate::kCommunicationError),
            static_cast<int>(PendingRWUpdate::kCount));
      }
      LOG(ERROR) << "Failed to connect USB.";
      fw_updater_->CloseUsb();

      if (connect_status == UsbConnectStatus::kUsbPathEmpty) {
        return HammerUpdater::RunStatus::kLostConnection;
      } else if (connect_status == UsbConnectStatus::kInvalidDevice) {
        LOG(ERROR) << "Invalid base connected.";
        dbus_wrapper_->SendSignal(kInvalidBaseConnectedSignal);
      }

      // If there is a "hammer-like" device attached, hammerd should
      // try to avoid running again when hammer jumps to RW. Use kNeedJump
      // to force this wait time before exiting.
      return HammerUpdater::RunStatus::kNeedJump;
    }

    // If this update is considered "critical", then we need to update the
    // firmware. This block is only run once at the first round of loop.
    if (!criticality_checked) {
      criticality_checked = true;

      if (!can_update) {
        PendingRWUpdate pending_metric = PendingRWUpdate::kCount;

        if (fw_updater_->IsCritical()) {
          LOG(INFO) << "Critical update available but update condition "
                    << "is set to 'never'; notify UI.";
          NotifyNeedUpdate();
          pending_metric = PendingRWUpdate::kCriticalUpdate;
        } else if (fw_updater_->VersionMismatch(SectionName::RW) ||
                   fw_updater_->CompareRollback() > 0) {
          // In theory, an increase in rollback number should imply a version
          // mismatch. Include both conditions here to simplify unittesting.
          pending_metric = PendingRWUpdate::kNonCriticalUpdate;
        } else {
          pending_metric = PendingRWUpdate::kNoUpdate;
        }

        metrics_->SendEnumToUMA(kMetricPendingRWUpdate,
                                static_cast<int>(pending_metric),
                                static_cast<int>(PendingRWUpdate::kCount));
      }
    }

    DLOG(INFO) << "Current task state: " << task_.ToString();
    status = RunOnce();
    task_.post_rw_jump = (status == HammerUpdater::RunStatus::kNeedJump);
    task_.post_rw_lock = (status == HammerUpdater::RunStatus::kNeedLock);
    switch (status) {
      case HammerUpdater::RunStatus::kNoUpdate:
        LOG(INFO) << "Hammer does not need to update.";
        fw_updater_->CloseUsb();
        return status;

      case HammerUpdater::RunStatus::kFatalError:
        LOG(ERROR) << "Hammer encountered a fatal error!";
        // Send the reset signal to hammer, and then prevent the next hammerd
        // process from being invoked.
        fw_updater_->SendSubcommand(UpdateExtraCommand::kImmediateReset);
        fw_updater_->CloseUsb();
        return HammerUpdater::RunStatus::kNeedReset;

      case HammerUpdater::RunStatus::kInvalidFirmware:
        // Send the JumpToRW to hammer, and then prevent the next hammerd
        // process from being invoked.
        fw_updater_->SendSubcommand(UpdateExtraCommand::kJumpToRW);
        fw_updater_->CloseUsb();
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        return HammerUpdater::RunStatus::kNeedJump;

      case HammerUpdater::RunStatus::kNeedReset:
        LOG(INFO) << "Reset hammer and run again. run_count=" << run_count;
        fw_updater_->SendSubcommand(UpdateExtraCommand::kImmediateReset);
        fw_updater_->CloseUsb();
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        continue;

      case HammerUpdater::RunStatus::kNeedLock:
        LOG(INFO) << "Request 'Jump to RW'. Hammer will reboot with locked RW. "
                  << "Run again. run_count=" << run_count;
        fw_updater_->SendSubcommand(UpdateExtraCommand::kJumpToRW);
        fw_updater_->CloseUsb();
        // TODO(kitching): Make RW jumps more robust by polling until
        // the jump completes (or fails).
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        continue;

      case HammerUpdater::RunStatus::kNeedJump:
        LOG(INFO) << "Jump to RW and run again. run_count=" << run_count;
        fw_updater_->SendSubcommand(UpdateExtraCommand::kJumpToRW);
        fw_updater_->CloseUsb();
        // TODO(kitching): Make RW jumps more robust by polling until
        // the jump completes (or fails).
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        continue;

      case HammerUpdater::RunStatus::kTouchpadMismatched:
        LOG(ERROR) << "Touchpad firmware is mismatched!";
        fw_updater_->CloseUsb();
        return HammerUpdater::RunStatus::kTouchpadMismatched;

      default:
        LOG(ERROR) << "Unknown RunStatus: " << static_cast<int>(status);
        fw_updater_->CloseUsb();
        return HammerUpdater::RunStatus::kFatalError;
    }
  }

  LOG(ERROR) << "Maximum run count exceeded (" << kMaximumRunCount << ")! ";
  return status;
}

HammerUpdater::RunStatus HammerUpdater::RunOnce() {
  // The first time we use SendFirstPdu it is to gather information about
  // hammer's running EC. We should use SendDone right away to get the EC
  // back into a state where we can send a subcommand.
  if (!fw_updater_->SendFirstPdu()) {
    LOG(ERROR) << "Failed to send the first PDU.";
    return HammerUpdater::RunStatus::kNeedReset;
  }
  fw_updater_->SendDone();
  LOG(INFO) << "### Current Section: "
            << ToString(fw_updater_->CurrentSection()) << " ###";

  // ********************** UNKNOWN **********************
  // If the layout of the firmware has changed, we cannot handle this case.
  if (fw_updater_->CurrentSection() == SectionName::Invalid) {
    LOG(INFO) << "Hammer is in RO but the firmware layout has changed.";
    return HammerUpdater::RunStatus::kInvalidFirmware;
  }

  // After sending first PDU, we get the information of current EC.
  // Check if the firmware version is mismatched or not.
  if (update_condition_ == UpdateCondition::kMismatch) {
    // In theory, an increase in rollback number should imply a version
    // mismatch. Include both conditions here to simplify unittesting.
    if (fw_updater_->VersionMismatch(SectionName::RW) ||
        fw_updater_->CompareRollback() > 0)
      task_.update_rw = true;
    if (fw_updater_->VersionMismatch(SectionName::RO))
      task_.update_ro = true;
  }

  // ********************** RW **********************
  // If EC already entered the RW section, then check if RW needs updating.
  // If an update is needed, request a hammer reset. Let the next invocation
  // of Run handle the update.
  if (fw_updater_->CurrentSection() == SectionName::RW) {
    if (task_.update_rw) {
      if (fw_updater_->ValidKey() && fw_updater_->CompareRollback() >= 0) {
        LOG(INFO) << "RW section needs update. Rebooting to RO.";
        if (fw_updater_->IsSectionLocked(SectionName::RW)) {
          fw_updater_->UnlockRW();
        }
        return HammerUpdater::RunStatus::kNeedReset;
      } else {
        task_.update_ro = true;
        LOG(INFO) << "RW section needs update, but local image is "
                  << "incompatible. Continuing to post-RW process; maybe "
                  << "RO can be updated.";
      }
    }
    return PostRWProcess();
  }

  // ********************** RO **********************
  // Current section is now guaranteed to be RO.  Deal with
  // each of three possible ongoing tasks:
  //   (1) jump to RW (failed, attempt update if possible)
  //   (2) inject entropy
  //   (3) update RW section
  if (task_.post_rw_jump || task_.inject_entropy ||
      (task_.update_rw && fw_updater_->ValidKey() &&
       fw_updater_->CompareRollback() >= 0)) {
    // If we have just finished a jump to RW, but we're still in RO, then
    // we should log the failure.
    if (task_.post_rw_jump) {
      LOG(ERROR) << "Failed to jump to RW. Need to update RW section.";
      if (update_condition_ == UpdateCondition::kNever) {
        LOG(INFO) << "RW is broken but update condition is 'never', notify UI.";
        NotifyNeedUpdate();
        return HammerUpdater::RunStatus::kFatalError;
      }
      if (!fw_updater_->ValidKey() || fw_updater_->CompareRollback() < 0) {
        LOG(ERROR) << "RW section is unusable, but local image is "
                   << "incompatible. Giving up.";
        // If both key and rollback are invalid, only the key will be
        // reported to UMA as invalid.
        metrics_->SendEnumToUMA(
            kMetricRWUpdateResult,
            static_cast<int>(fw_updater_->ValidKey()
                                 ? RWUpdateResult::kRollbackDisallowed
                                 : RWUpdateResult::kInvalidKey),
            static_cast<int>(RWUpdateResult::kCount));
        return HammerUpdater::RunStatus::kFatalError;
      }
    }

    // EC is still running in RO section. Send "Stay in RO" command before
    // continuing.
    LOG(INFO) << "Sending stay in RO command.";
    if (!fw_updater_->SendSubcommand(UpdateExtraCommand::kStayInRO)) {
      LOG(ERROR) << "Failed to stay in RO.";
      return HammerUpdater::RunStatus::kNeedReset;
    }

    if (task_.inject_entropy) {
      bool ret = fw_updater_->InjectEntropy();
      if (ret) {
        task_.inject_entropy = false;
        LOG(INFO) << "Successfully injected entropy.";
        return HammerUpdater::RunStatus::kNeedReset;
      }
      LOG(ERROR) << "Failed to inject entropy.";
      return HammerUpdater::RunStatus::kFatalError;
    }

    if (fw_updater_->IsSectionLocked(SectionName::RW)) {
      LOG(INFO) << "Unlock RW section, and reset EC.";
      fw_updater_->UnlockRW();
      return HammerUpdater::RunStatus::kNeedReset;
    }

    // Now RW section needs an update, and it is not locked. Let's update!
    return UpdateRW();
  }

  // Now we need to jump to RW section.  When requesting 'Jump to RW', hammer
  // responds differently depending on the state of RO and RW locks:
  //   (1) RO is unlocked:
  //       hammerd will jump to RW regardless of wether or not RW is locked.
  //   (2) RO is locked:
  //       (a) RW is locked: hammer will jump to RW.
  //       (b) RW is unlocked: hammer will set RW to be locked on next boot, and
  //           reset itself.
  // In the case of (2)(b), after requesting the jump, hammer will reset itself
  // and end up in RO.  Now we fall under the case of (2)(1) and may request the
  // jump again.
  // TODO(b/117909308): add unittest.
  if (fw_updater_->IsSectionLocked(SectionName::RO) &&
      !fw_updater_->IsSectionLocked(SectionName::RW)) {
    if (task_.post_rw_lock) {
      LOG(INFO) << "Failed to lock RW section... update RW section again.";
      return UpdateRW();
    }
    LOG(INFO) << "RO is locked but RW is not. "
              << "Lock RW by asking hammer to reset.";
    return HammerUpdater::RunStatus::kNeedLock;
  }
  task_.post_rw_lock = false;

  LOG(INFO) << "No need to update RW. Jump to RW section.";
  return HammerUpdater::RunStatus::kNeedJump;
}

HammerUpdater::RunStatus HammerUpdater::PostRWProcess() {
  LOG(INFO) << "Start the post-RW process.";
  HammerUpdater::RunStatus ret;

  // Update RO section.
  ret = UpdateRO();
  if (ret != HammerUpdater::RunStatus::kNoUpdate) {
    return ret;
  }

  // Trigger the retry if update fails.
  ret = RunTouchpadUpdater();
  if (ret != HammerUpdater::RunStatus::kTouchpadUpToDate) {
    LOG(INFO) << "Touchpad update failure.";
    return ret;
  }

  // Pair with hammer.
  if (!at_boot_) {
    ret = Pair();
    if (ret != HammerUpdater::RunStatus::kNoUpdate) {
      return ret;
    }
  }

  // TODO(akahuang): Rollback increment.
  // All process are done.
  return HammerUpdater::RunStatus::kNoUpdate;
}

HammerUpdater::RunStatus HammerUpdater::UpdateRO() {
  // RO section should be unlocked on dogfood devices -- no need to first run
  // UnLockSection.
  // TODO(kitching): Consider adding a UI warning to make sure a dogfood user
  // does not detach the base at the wrong time, as that could brick it.
  if (fw_updater_->IsSectionLocked(SectionName::RO)) {
    LOG(INFO) << "RO section is locked. Update infeasible.";
    return HammerUpdater::RunStatus::kNoUpdate;
  }
  if (!task_.update_ro) {
    LOG(INFO) << "RO section is unlocked, but update not needed.";
    return HammerUpdater::RunStatus::kNoUpdate;
  }
  LOG(INFO) << "RO is unlocked and update is needed. Starting update.";
  NotifyUpdateStarted();
  bool ret = fw_updater_->TransferImage(SectionName::RO);
  task_.update_ro = !ret;
  metrics_->SendEnumToUMA(
      kMetricROUpdateResult,
      static_cast<int>(ret ? ROUpdateResult::kSucceeded
                           : ROUpdateResult::kTransferFailed),
      static_cast<int>(ROUpdateResult::kCount));
  LOG(INFO) << "RO update " << (ret ? "passed." : "failed.");
  // In the case that the update failed, a reset will either brick the device,
  // or get it back into a normal state.
  return HammerUpdater::RunStatus::kNeedReset;
}

HammerUpdater::RunStatus HammerUpdater::Pair() {
  ChallengeStatus status =
      pair_manager_->PairChallenge(fw_updater_.get(), dbus_wrapper_.get());
  PairResult metric_result = PairResult::kUnknownError;
  HammerUpdater::RunStatus ret = HammerUpdater::RunStatus::kFatalError;

  switch (status) {
    case ChallengeStatus::kChallengePassed:
      metric_result = PairResult::kChallengePassed;
      // TODO(akahuang): Check if the base is swapped.
      ret = HammerUpdater::RunStatus::kNoUpdate;
      break;

    case ChallengeStatus::kNeedInjectEntropy:
      metric_result = PairResult::kNeedInjectEntropy;
      if (fw_updater_->IsRollbackLocked()) {
        if (!fw_updater_->UnlockRollback()) {
          LOG(ERROR) << "Failed to unlock rollback. Skip injecting entropy.";
          ret = HammerUpdater::RunStatus::kFatalError;
          break;
        }
      }
      task_.inject_entropy = true;
      ret = HammerUpdater::RunStatus::kNeedReset;
      break;

    case ChallengeStatus::kChallengeFailed:
      metric_result = PairResult::kChallengeFailed;
      break;

    case ChallengeStatus::kConnectionError:
      // Do not send UMA if the base is disconnected.
      metric_result = PairResult::kCount;
      ret = HammerUpdater::RunStatus::kLostConnection;
      break;

    case ChallengeStatus::kUnknownError:
      break;
  }

  if (metric_result != PairResult::kCount) {
    metrics_->SendEnumToUMA(kMetricPairResult, static_cast<int>(metric_result),
                            static_cast<int>(PairResult::kCount));
  }
  return ret;
}

void HammerUpdater::WaitUsbReady(HammerUpdater::RunStatus status) {
  // The time period after which hammer automatically jumps to RW section.
  constexpr unsigned int kJumpToRWTimeMs = 1000;
  // The time period from USB device ready to udev invoking hammerd.
  constexpr unsigned int kUdevGuardTimeMs = 1500;

  // If hammerd send reset or jump to RW signal at the last run, hammer will
  // re-connect to the AP and udev will trigger hammerd again. We MUST prohibit
  // the next invocation, otherwise udev will invoke hammerd infinitely.
  //
  // The timing of invocation might be entering into RO section or RW section.
  // Therefore we might wait for USB device once when sending JumpToRW, and wait
  // twice when sending Reset signal.
  if (status == HammerUpdater::RunStatus::kNeedReset ||
      status == HammerUpdater::RunStatus::kNeedJump) {
    LOG(INFO) << "Wait for USB device ready...";
    UsbConnectStatus usb_connection = fw_updater_->TryConnectUsb();
    fw_updater_->CloseUsb();
    // If there is no device there, don't bother waiting.
    if (usb_connection == UsbConnectStatus::kUsbPathEmpty) {
      return;
    }
    if (status == HammerUpdater::RunStatus::kNeedReset) {
      LOG(INFO) << "USB device probably in RO, waiting for it to enter RW.";
      base::PlatformThread::Sleep(
          base::TimeDelta::FromMilliseconds(kJumpToRWTimeMs));

      usb_connection = fw_updater_->TryConnectUsb();
      fw_updater_->CloseUsb();
      // If there is no device there, don't bother waiting.
      if (usb_connection == UsbConnectStatus::kUsbPathEmpty) {
        return;
      }
    }

    LOG(INFO) << "Now USB device should be in RW. Wait " << kUdevGuardTimeMs
              << "ms to prevent udev invoking next process.";
    base::PlatformThread::Sleep(
        base::TimeDelta::FromMilliseconds(kUdevGuardTimeMs));
    LOG(INFO) << "Finish the infinite loop prevention.";
  }
}

void HammerUpdater::NotifyNeedUpdate() {
  DCHECK(update_condition_ == UpdateCondition::kNever);
  if (!dbus_notified_) {
    dbus_notified_ = true;
    dbus_wrapper_->SendSignal(kBaseFirmwareNeedUpdateSignal);
  }
}

void HammerUpdater::NotifyUpdateStarted() {
  DCHECK(update_condition_ != UpdateCondition::kNever);
  if (!dbus_notified_) {
    dbus_notified_ = true;
    dbus_wrapper_->SendSignal(kBaseFirmwareUpdateStartedSignal);
  }
}

void HammerUpdater::NotifyUpdateFinished(bool is_success) {
  DCHECK(update_condition_ != UpdateCondition::kNever);
  // If we tried to update the firmware, send a signal to notify the updating is
  // finished.
  if (dbus_notified_) {
    dbus_notified_ = false;
    dbus_wrapper_->SendSignal(is_success ? kBaseFirmwareUpdateSucceededSignal
                                         : kBaseFirmwareUpdateFailedSignal);
  }
}

std::string HammerUpdater::VersionString(TouchpadInfo info) {
  std::string base_fw_ver;
  if (info.vendor == ST_VENDOR_ID) {
    base_fw_ver =
        base::StringPrintf(kStFormatString, info.st.fw_version & 0x00ff,
                           (info.st.fw_version & 0xff00) >> 8);
  } else {
    base_fw_ver = base::StringPrintf(kElanFormatString, info.elan.fw_version);
  }
  return base_fw_ver;
}

std::string HammerUpdater::VendorString(TouchpadInfo info) {
  std::string vendor;
  switch (info.vendor) {
    case ST_VENDOR_ID:
      return "ST";
      break;
    case ELAN_VENDOR_ID:
      return "ELAN";
      break;
    default:
      return "UNKNOWN";
      break;
  }
}

HammerUpdater::RunStatus HammerUpdater::RunTouchpadUpdater() {
  if (!touchpad_image_.size()) {  // We are missing the touchpad file.
    LOG(INFO) << "Touchpad will remain unmodified as binary is not provided.";
    return HammerUpdater::RunStatus::kTouchpadUpToDate;
  }

  LOG(INFO) << "Loading touchpad firmware image.";
  if (!fw_updater_->LoadTouchpadImage(touchpad_image_)) {
    LOG(ERROR) << "Failed to load touchpad image.";
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  // Make request to get infomation from hammer.
  TouchpadInfo response;
  if (!fw_updater_->SendSubcommandReceiveResponse(
          UpdateExtraCommand::kTouchpadInfo, "",
          reinterpret_cast<void*>(&response), sizeof(response))) {
    LOG(ERROR) << "Not able to get touchpad info from base.";
    return HammerUpdater::RunStatus::kNeedReset;
  }
  LOG(INFO) << "Current touchpad information from base:";
  LOG(INFO) << "status: 0x" << std::hex << static_cast<int>(response.status);
  LOG(INFO) << "vendor: 0x" << std::hex << response.vendor << " "
            << VendorString(response);
  LOG(INFO) << "fw_address: 0x" << std::hex << response.fw_address;
  LOG(INFO) << "fw_size: " << response.fw_size << " bytes";
  LOG(INFO) << "allowed_fw_hash: 0x"
            << base::HexEncode(response.allowed_fw_hash, SHA256_DIGEST_LENGTH);
  LOG(INFO) << "product_id: " << response.elan.id << ".0";

  std::string base_fw_ver = VersionString(response);
  LOG(INFO) << "fw_ver: " << base_fw_ver;

  LOG(INFO) << "fw_checksum: 0x" << std::hex << response.elan.fw_checksum;

  if (response.status != static_cast<uint8_t>(EcResponseStatus::kSuccess)) {
    // EC must be really screw up to get this.
    LOG(ERROR) << "Base can't read I2C bus normally. Abort touchpad update.";
    return HammerUpdater::RunStatus::kNeedReset;
  }

  // Check if the image size matches IC size.
  if (touchpad_image_.size() != response.fw_size) {
    LOG(ERROR) << "Local touchpad binary doesn't match remote IC size.";
    LOG(ERROR) << "Local=" << touchpad_image_.size() << " bytes."
               << "Remote=" << response.fw_size << " bytes.";
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  // Check if the SHA value of the touchpad firmware (entire file) has same
  // hash as the record in RW firmware. We check this prior to update
  // because if an individual chunk verification fail, the touchpad might
  // get into a weird state (only part of the flash is updated).
  uint8_t digest[SHA256_DIGEST_LENGTH];

  SHA256(reinterpret_cast<const uint8_t*>(touchpad_image_.data()),
         response.fw_size, reinterpret_cast<unsigned char*>(&digest));
  LOG(INFO) << "Computed local touchpad firmware hash: 0x"
            << base::HexEncode(digest, SHA256_DIGEST_LENGTH);
  if (std::memcmp(digest, response.allowed_fw_hash, SHA256_DIGEST_LENGTH)) {
    LOG(ERROR) << "Touchpad firmware mismatches hash in RW EC.";
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  // Check if the product_id is matched. Currently, Elan uses numbers for
  // product_id, but it might be different for other vendors. For example,
  // in chromeos-touch-firmware-nyan package, Cypress uses product id like
  // CYTRA-103006-00.
  if (base::StringPrintf(kElanFormatString, response.elan.id) !=
      touchpad_product_id_) {
    LOG(ERROR) << "product_id mismatch. Local: " << touchpad_product_id_;
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  if (!task_.update_tp) {
    // If fw_ver match, then we skip the update. Otherwise, flash it.

    LOG(INFO) << base::StringPrintf(
        "Checking touchpad firmware version: Local(%s) vs. Base(%s)",
        touchpad_fw_ver_.c_str(), base_fw_ver.c_str());

    if (base_fw_ver == touchpad_fw_ver_) {
      LOG(INFO) << "Version matched, skip update.";
      return HammerUpdater::RunStatus::kTouchpadUpToDate;
    }
    // Version mismatches. However, if update condition is "never", then
    // we should notify UI when firmware is broken, or just skip update.
    if (update_condition_ == UpdateCondition::kNever) {
      if (response.elan.fw_version == kElanBrokenFwVersion) {
        LOG(INFO) << "Touchpad firmware is broken but never update, notify UI.";
        NotifyNeedUpdate();
        return HammerUpdater::RunStatus::kTouchpadMismatched;
      }
      LOG(INFO) << "Pretend touchpad firmware is up to date.";
      return HammerUpdater::RunStatus::kTouchpadUpToDate;
    }
    // OK, we really need to update touchpad now.
    task_.update_tp = true;
  }
  LOG(INFO) << "Update touchpad firmware, notify UI";
  NotifyUpdateStarted();
  bool ret = fw_updater_->TransferTouchpadFirmware(response.fw_address,
                                                   response.fw_size);
  task_.update_tp = !ret;
  return ret ? HammerUpdater::RunStatus::kTouchpadUpToDate
             : HammerUpdater::RunStatus::kNeedReset;
}

bool HammerUpdater::ParseTouchpadInfoFromFilename(
    const std::string& filename,
    std::string* touchpad_product_id,
    std::string* touchpad_fw_ver) {
  base::FilePath real_path;
  bool ret = base::NormalizeFilePath(base::FilePath(filename), &real_path);
  std::string basename = real_path.BaseName().value();

  LOG(INFO) << "Canonical path for touchpad firmware : " << real_path.value();
  // Filename should be in format of <product_id>_<fw_ver>.bin
  pcrecpp::RE re("(.+)_([\\.\\d]+?)\\.bin");
  ret &= re.FullMatch(basename, touchpad_product_id, touchpad_fw_ver);
  LOG(INFO) << "Parsed product_id : " << *touchpad_product_id;
  LOG(INFO) << "Parsed fw_ver : " << *touchpad_fw_ver;

  return ret;
}

void HammerUpdater::SetInjectEntropyFlag(bool inject_entropy) {
  LOG(INFO) << "inject_entropy is set to " << inject_entropy;
  task_.inject_entropy = inject_entropy;
}

}  // namespace hammerd
