// Copyright 2021 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 "rmad/utils/cbi_utils_impl.h"

#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <re2/re2.h>

#include "rmad/utils/cmd_utils_impl.h"

namespace {

constexpr char kEctoolCmdPath[] = "/usr/sbin/ectool";
constexpr char kEctoolIntValRegex[] = R"(As uint: (\d+))";

constexpr int kCbiTagSkuId = 2;
constexpr int kCbiTagDramPartNum = 3;
constexpr int kCbiTagSSFC = 8;

}  // namespace

namespace rmad {

CbiUtilsImpl::CbiUtilsImpl() {
  cmd_utils_ = std::make_unique<CmdUtilsImpl>();
}

CbiUtilsImpl::CbiUtilsImpl(std::unique_ptr<CmdUtils> cmd_utils)
    : cmd_utils_(std::move(cmd_utils)) {}

bool CbiUtilsImpl::GetSku(uint64_t* sku) const {
  CHECK(sku);

  return GetCbi(kCbiTagSkuId, sku);
}

bool CbiUtilsImpl::GetDramPartNum(std::string* dram_part_num) const {
  CHECK(dram_part_num);

  return GetCbi(kCbiTagDramPartNum, dram_part_num);
}

bool CbiUtilsImpl::GetSSFC(uint32_t* ssfc) const {
  CHECK(ssfc);

  uint64_t buf;
  if (!GetCbi(kCbiTagSSFC, &buf)) {
    return false;
  }

  if (buf > static_cast<uint64_t>(std::numeric_limits<uint32_t>::max())) {
    return false;
  }

  *ssfc = static_cast<uint32_t>(buf);
  return true;
}

bool CbiUtilsImpl::SetSku(uint64_t sku) {
  int byte_size = 0;
  uint64_t tmp = sku;

  // To tackle |sku| = 0, we use do-while to ensure that |byte_size| >= 1.
  do {
    tmp >>= 8;
    byte_size++;
  } while (tmp);

  return SetCbi(kCbiTagSkuId, sku, byte_size);
}

bool CbiUtilsImpl::SetDramPartNum(const std::string& dram_part_num) {
  return SetCbi(kCbiTagDramPartNum, dram_part_num);
}

bool CbiUtilsImpl::SetSSFC(uint32_t ssfc) {
  // For SSFC, we always use 4 bytes.
  return SetCbi(kCbiTagSSFC, ssfc, 4);
}

bool CbiUtilsImpl::SetCbi(int tag, const std::string& value, int set_flag) {
  std::vector<std::string> argv{kEctoolCmdPath,
                                "cbi",
                                "set",
                                base::NumberToString(tag),
                                value,
                                "0",
                                base::NumberToString(set_flag)};
  static std::string unused_output;
  return cmd_utils_->GetOutput(argv, &unused_output);
}

bool CbiUtilsImpl::GetCbi(int tag, std::string* value, int get_flag) const {
  CHECK(value != nullptr);

  std::vector<std::string> argv{kEctoolCmdPath, "cbi", "get",
                                base::NumberToString(tag),
                                base::NumberToString(get_flag)};
  if (!cmd_utils_->GetOutput(argv, value)) {
    return false;
  }

  base::TrimWhitespaceASCII(*value, base::TRIM_TRAILING, value);
  return true;
}

bool CbiUtilsImpl::SetCbi(int tag, uint64_t value, int size, int set_flag) {
  CHECK_GE(size, 1);
  CHECK_LE(size, 8);
  CHECK(size == 8 || 1ull << (size * 8) > value);

  std::vector<std::string> argv{kEctoolCmdPath,
                                "cbi",
                                "set",
                                base::NumberToString(tag),
                                base::NumberToString(value),
                                base::NumberToString(size),
                                base::NumberToString(set_flag)};
  static std::string unused_output;
  return cmd_utils_->GetOutput(argv, &unused_output);
}

bool CbiUtilsImpl::GetCbi(int tag, uint64_t* value, int get_flag) const {
  CHECK(value != nullptr);

  std::vector<std::string> argv{kEctoolCmdPath, "cbi", "get",
                                base::NumberToString(tag),
                                base::NumberToString(get_flag)};
  std::string output;
  if (!cmd_utils_->GetOutput(argv, &output)) {
    return false;
  }

  if (!re2::RE2::PartialMatch(output, kEctoolIntValRegex, value)) {
    LOG(ERROR) << "Failed to parse output from ectool";
    return false;
  }

  return true;
}

}  // namespace rmad
