// Copyright 2019 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 "diagnostics/cros_healthd/cros_healthd_routine_service_impl.h"

#include <limits>
#include <string>
#include <utility>

#include <base/logging.h>

namespace diagnostics {
namespace mojo_ipc = ::chromeos::cros_healthd::mojom;

namespace {

void SetErrorRoutineUpdate(const std::string& status_message,
                           mojo_ipc::RoutineUpdate* response) {
  mojo_ipc::NonInteractiveRoutineUpdate noninteractive_update;
  noninteractive_update.status = mojo_ipc::DiagnosticRoutineStatusEnum::kError;
  noninteractive_update.status_message = status_message;
  response->routine_update_union->set_noninteractive_update(
      noninteractive_update.Clone());
  response->progress_percent = 0;
}

}  // namespace

CrosHealthdRoutineServiceImpl::CrosHealthdRoutineServiceImpl(
    Context* context, CrosHealthdRoutineFactory* routine_factory)
    : context_(context), routine_factory_(routine_factory) {
  DCHECK(context_);
  DCHECK(routine_factory_);
  PopulateAvailableRoutines();
}

CrosHealthdRoutineServiceImpl::~CrosHealthdRoutineServiceImpl() = default;

std::vector<mojo_ipc::DiagnosticRoutineEnum>
CrosHealthdRoutineServiceImpl::GetAvailableRoutines() {
  return std::vector<mojo_ipc::DiagnosticRoutineEnum>(
      available_routines_.begin(), available_routines_.end());
}

void CrosHealthdRoutineServiceImpl::RunBatteryCapacityRoutine(
    uint32_t low_mah,
    uint32_t high_mah,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeBatteryCapacityRoutine(low_mah, high_mah),
             mojo_ipc::DiagnosticRoutineEnum::kBatteryCapacity, id, status);
}

void CrosHealthdRoutineServiceImpl::RunBatteryHealthRoutine(
    uint32_t maximum_cycle_count,
    uint32_t percent_battery_wear_allowed,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeBatteryHealthRoutine(
                 maximum_cycle_count, percent_battery_wear_allowed),
             mojo_ipc::DiagnosticRoutineEnum::kBatteryHealth, id, status);
}

void CrosHealthdRoutineServiceImpl::RunUrandomRoutine(
    uint32_t length_seconds,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeUrandomRoutine(length_seconds),
             mojo_ipc::DiagnosticRoutineEnum::kUrandom, id, status);
}

void CrosHealthdRoutineServiceImpl::RunSmartctlCheckRoutine(
    int32_t* id, mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeSmartctlCheckRoutine(),
             mojo_ipc::DiagnosticRoutineEnum::kSmartctlCheck, id, status);
}

void CrosHealthdRoutineServiceImpl::RunAcPowerRoutine(
    mojo_ipc::AcPowerStatusEnum expected_status,
    const base::Optional<std::string>& expected_power_type,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeAcPowerRoutine(expected_status,
                                                  expected_power_type),
             mojo_ipc::DiagnosticRoutineEnum::kAcPower, id, status);
}

void CrosHealthdRoutineServiceImpl::RunCpuCacheRoutine(
    base::TimeDelta exec_duration,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeCpuCacheRoutine(exec_duration),
             mojo_ipc::DiagnosticRoutineEnum::kCpuCache, id, status);
}

void CrosHealthdRoutineServiceImpl::RunCpuStressRoutine(
    base::TimeDelta exec_duration,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeCpuStressRoutine(exec_duration),
             mojo_ipc::DiagnosticRoutineEnum::kCpuStress, id, status);
}

void CrosHealthdRoutineServiceImpl::RunFloatingPointAccuracyRoutine(
    base::TimeDelta exec_duration,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeFloatingPointAccuracyRoutine(exec_duration),
             mojo_ipc::DiagnosticRoutineEnum::kFloatingPointAccuracy, id,
             status);
}

void CrosHealthdRoutineServiceImpl::RunNvmeWearLevelRoutine(
    uint32_t wear_level_threshold,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeNvmeWearLevelRoutine(
                 context_->debugd_adapter(), wear_level_threshold),
             mojo_ipc::DiagnosticRoutineEnum::kNvmeWearLevel, id, status);
}

void CrosHealthdRoutineServiceImpl::RunNvmeSelfTestRoutine(
    mojo_ipc::NvmeSelfTestTypeEnum nvme_self_test_type,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeNvmeSelfTestRoutine(
                 context_->debugd_adapter(), nvme_self_test_type),
             mojo_ipc::DiagnosticRoutineEnum::kNvmeSelfTest, id, status);
}

void CrosHealthdRoutineServiceImpl::RunDiskReadRoutine(
    mojo_ipc::DiskReadRoutineTypeEnum type,
    base::TimeDelta exec_duration,
    uint32_t file_size_mb,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(
      routine_factory_->MakeDiskReadRoutine(type, exec_duration, file_size_mb),
      mojo_ipc::DiagnosticRoutineEnum::kDiskRead, id, status);
}

void CrosHealthdRoutineServiceImpl::RunPrimeSearchRoutine(
    base::TimeDelta exec_duration,
    uint64_t max_num,
    int32_t* id,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakePrimeSearchRoutine(exec_duration, max_num),
             mojo_ipc::DiagnosticRoutineEnum::kPrimeSearch, id, status);
}

void CrosHealthdRoutineServiceImpl::RunBatteryDischargeRoutine(
    base::TimeDelta exec_duration,
    uint32_t maximum_discharge_percent_allowed,
    int32_t* id,
    MojomCrosHealthdDiagnosticRoutineStatusEnum* status) {
  RunRoutine(routine_factory_->MakeBatteryDischargeRoutine(
                 exec_duration, maximum_discharge_percent_allowed),
             mojo_ipc::DiagnosticRoutineEnum::kBatteryDischarge, id, status);
}

void CrosHealthdRoutineServiceImpl::GetRoutineUpdate(
    int32_t uuid,
    mojo_ipc::DiagnosticRoutineCommandEnum command,
    bool include_output,
    mojo_ipc::RoutineUpdate* response) {
  auto itr = active_routines_.find(uuid);
  if (itr == active_routines_.end()) {
    LOG(ERROR) << "Bad uuid in GetRoutineUpdateRequest.";
    SetErrorRoutineUpdate("Specified routine does not exist.", response);
    return;
  }

  auto* routine = itr->second.get();
  switch (command) {
    case mojo_ipc::DiagnosticRoutineCommandEnum::kContinue:
      routine->Resume();
      break;
    case mojo_ipc::DiagnosticRoutineCommandEnum::kCancel:
      routine->Cancel();
      break;
    case mojo_ipc::DiagnosticRoutineCommandEnum::kGetStatus:
      // Retrieving the status and output of a routine is handled below.
      break;
    case mojo_ipc::DiagnosticRoutineCommandEnum::kRemove:
      routine->PopulateStatusUpdate(response, include_output);
      if (response->routine_update_union->is_noninteractive_update()) {
        response->routine_update_union->get_noninteractive_update()->status =
            MojomCrosHealthdDiagnosticRoutineStatusEnum::kRemoved;
      }
      active_routines_.erase(itr);
      // |routine| is invalid at this point!
      return;
  }

  routine->PopulateStatusUpdate(response, include_output);
}

void CrosHealthdRoutineServiceImpl::RunRoutine(
    std::unique_ptr<DiagnosticRoutine> routine,
    mojo_ipc::DiagnosticRoutineEnum routine_enum,
    int32_t* id_out,
    mojo_ipc::DiagnosticRoutineStatusEnum* status) {
  DCHECK(routine);
  DCHECK(id_out);
  DCHECK(status);

  if (!available_routines_.count(routine_enum)) {
    *status = mojo_ipc::DiagnosticRoutineStatusEnum::kUnsupported;
    *id_out = mojo_ipc::kFailedToStartId;
    LOG(ERROR) << routine_enum << " is not supported on this device";
    return;
  }

  CHECK(next_id_ < std::numeric_limits<int32_t>::max())
      << "Maximum number of routines exceeded.";

  routine->Start();
  int32_t id = next_id_;
  DCHECK(active_routines_.find(id) == active_routines_.end());
  active_routines_[id] = std::move(routine);
  ++next_id_;

  *id_out = id;
  *status = active_routines_[id]->GetStatus();
}

void CrosHealthdRoutineServiceImpl::PopulateAvailableRoutines() {
  // Routines that are supported on all devices.
  available_routines_ = {
      mojo_ipc::DiagnosticRoutineEnum::kUrandom,
      mojo_ipc::DiagnosticRoutineEnum::kAcPower,
      mojo_ipc::DiagnosticRoutineEnum::kCpuCache,
      mojo_ipc::DiagnosticRoutineEnum::kCpuStress,
      mojo_ipc::DiagnosticRoutineEnum::kFloatingPointAccuracy,
      mojo_ipc::DiagnosticRoutineEnum::kPrimeSearch};

  if (context_->system_config()->HasBattery()) {
    available_routines_.insert(
        mojo_ipc::DiagnosticRoutineEnum::kBatteryCapacity);
    available_routines_.insert(mojo_ipc::DiagnosticRoutineEnum::kBatteryHealth);
    available_routines_.insert(
        mojo_ipc::DiagnosticRoutineEnum::kBatteryDischarge);
  }

  if (context_->system_config()->NvmeSupported()) {
    available_routines_.insert(mojo_ipc::DiagnosticRoutineEnum::kNvmeWearLevel);
    available_routines_.insert(mojo_ipc::DiagnosticRoutineEnum::kNvmeSelfTest);
  }

  if (context_->system_config()->SmartCtlSupported()) {
    available_routines_.insert(mojo_ipc::DiagnosticRoutineEnum::kSmartctlCheck);
  }

  if (context_->system_config()->FioSupported()) {
    available_routines_.insert(mojo_ipc::DiagnosticRoutineEnum::kDiskRead);
  }
}

}  // namespace diagnostics
