// Copyright 2020 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/fetchers/system_fetcher.h"

#include <string>
#include <utility>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>
#include <base/system/sys_info.h>

#include "diagnostics/cros_healthd/utils/error_utils.h"
#include "diagnostics/cros_healthd/utils/file_utils.h"

namespace diagnostics {

constexpr char kRelativeDmiInfoPath[] = "sys/class/dmi/id";
constexpr char kRelativeVpdRoPath[] = "sys/firmware/vpd/ro/";
constexpr char kRelativeVpdRwPath[] = "sys/firmware/vpd/rw/";

constexpr char kFirstPowerDateFileName[] = "ActivateDate";
constexpr char kManufactureDateFileName[] = "mfg_date";
constexpr char kSkuNumberFileName[] = "sku_number";
constexpr char kBiosVersionFileName[] = "bios_version";
constexpr char kBoardNameFileName[] = "board_name";
constexpr char kBoardVersionFileName[] = "board_version";
constexpr char kChassisTypeFileName[] = "chassis_type";
constexpr char kProductNameFileName[] = "product_name";

namespace {

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

// Fetches information from DMI. Since there are several devices that do not
// provide DMI information, these fields are optional in SystemInfo. As a
// result, a missing DMI file does not indicate a ProbeError. A ProbeError is
// reported when the "chassis_type" field cannot be successfully parsed into an
// unsigned integer.
base::Optional<mojo_ipc::ProbeErrorPtr> FetchDmiInfo(
    const base::FilePath& root_dir, mojo_ipc::SystemInfo* output_info) {
  const base::FilePath& relative_dmi_info_path =
      root_dir.Append(kRelativeDmiInfoPath);
  std::string bios_version;
  if (ReadAndTrimString(relative_dmi_info_path, kBiosVersionFileName,
                        &bios_version)) {
    output_info->bios_version = bios_version;
  }

  std::string board_name;
  if (ReadAndTrimString(relative_dmi_info_path, kBoardNameFileName,
                        &board_name)) {
    output_info->board_name = board_name;
  }

  std::string board_version;
  if (ReadAndTrimString(relative_dmi_info_path, kBoardVersionFileName,
                        &board_version)) {
    output_info->board_version = board_version;
  }

  std::string chassis_type_str;
  if (ReadAndTrimString(relative_dmi_info_path, kChassisTypeFileName,
                        &chassis_type_str)) {
    uint64_t chassis_type;
    if (base::StringToUint64(chassis_type_str, &chassis_type)) {
      output_info->chassis_type = mojo_ipc::UInt64Value::New(chassis_type);
    } else {
      return CreateAndLogProbeError(
          mojo_ipc::ErrorType::kParseError,
          base::StringPrintf("Failed to convert chassis_type: %s",
                             chassis_type_str.c_str()));
    }
  }

  std::string product_name;
  if (ReadAndTrimString(relative_dmi_info_path, kProductNameFileName,
                        &product_name)) {
    output_info->product_name = product_name;
  }

  return base::nullopt;
}

}  // namespace

SystemFetcher::SystemFetcher(Context* context) : context_(context) {
  DCHECK(context_);
}

SystemFetcher::~SystemFetcher() = default;

base::Optional<mojo_ipc::ProbeErrorPtr> SystemFetcher::FetchCachedVpdInfo(
    const base::FilePath& root_dir, mojo_ipc::SystemInfo* output_info) {
  std::string first_power_date;
  if (ReadAndTrimString(root_dir.Append(kRelativeVpdRwPath),
                        kFirstPowerDateFileName, &first_power_date)) {
    output_info->first_power_date = first_power_date;
  }

  const base::FilePath relative_vpd_ro_dir =
      root_dir.Append(kRelativeVpdRoPath);
  std::string manufacture_date;
  if (ReadAndTrimString(relative_vpd_ro_dir, kManufactureDateFileName,
                        &manufacture_date)) {
    output_info->manufacture_date = manufacture_date;
  }

  if (context_->system_config()->HasSkuNumber()) {
    std::string sku_number;
    if (!ReadAndTrimString(relative_vpd_ro_dir, kSkuNumberFileName,
                           &sku_number)) {
      return CreateAndLogProbeError(
          mojo_ipc::ErrorType::kFileReadError,
          "Unable to read VPD file " + std::string(kSkuNumberFileName) +
              " at path " + relative_vpd_ro_dir.value().c_str());
    }
    output_info->product_sku_number = sku_number;
  }

  return base::nullopt;
}

void SystemFetcher::FetchMasterConfigInfo(mojo_ipc::SystemInfo* output_info) {
  output_info->marketing_name = context_->system_config()->GetMarketingName();
}

base::Optional<mojo_ipc::ProbeErrorPtr> SystemFetcher::FetchOsVersion(
    mojo_ipc::OsVersion* os_version) {
  std::string milestone;
  std::string build;
  std::string patch;
  std::string release_channel;

  if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_CHROME_MILESTONE",
                                         &milestone)) {
    return CreateAndLogProbeError(
        mojo_ipc::ErrorType::kFileReadError,
        "Unable to read OS milestone from /etc/lsb-release");
  }

  if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BUILD_NUMBER",
                                         &build)) {
    return CreateAndLogProbeError(
        mojo_ipc::ErrorType::kFileReadError,
        "Unable to read OS build number from /etc/lsb-release");
  }

  if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_PATCH_NUMBER",
                                         &patch)) {
    return CreateAndLogProbeError(
        mojo_ipc::ErrorType::kFileReadError,
        "Unable to read OS patch number from /etc/lsb-release");
  }

  if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_TRACK",
                                         &release_channel)) {
    return CreateAndLogProbeError(
        mojo_ipc::ErrorType::kFileReadError,
        "Unable to read OS release track from /etc/lsb-release");
  }

  os_version->release_milestone = milestone;
  os_version->build_number = build;
  os_version->patch_number = patch;
  os_version->release_channel = release_channel;
  return base::nullopt;
}

mojo_ipc::SystemResultPtr SystemFetcher::FetchSystemInfo(
    const base::FilePath& root_dir) {
  mojo_ipc::SystemInfo system_info;

  base::Optional<mojo_ipc::ProbeErrorPtr> error =
      FetchCachedVpdInfo(root_dir, &system_info);
  if (error.has_value())
    return mojo_ipc::SystemResult::NewError(std::move(error.value()));

  FetchMasterConfigInfo(&system_info);
  error = FetchDmiInfo(root_dir, &system_info);
  if (error.has_value())
    return mojo_ipc::SystemResult::NewError(std::move(error.value()));

  system_info.os_version = mojo_ipc::OsVersion::New();
  error = FetchOsVersion(system_info.os_version.get());
  if (error.has_value()) {
    return mojo_ipc::SystemResult::NewError(std::move(error.value()));
  }

  return mojo_ipc::SystemResult::NewSystemInfo(system_info.Clone());
}

}  // namespace diagnostics
