// Copyright 2017 The Fuchsia 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 "src/system_data/system_data.h"

#include <cstring>
#include <map>
#include <string>
#include <utility>

#include "src/logger/internal_metrics_config.cb.h"
#include "src/logging.h"
#include "src/pb/common.pb.h"
#include "src/pb/observation_batch.pb.h"

namespace cobalt::system_data {

namespace {

#if defined(__x86_64__)

// This identifies board names for x86 Systems.
// If the signature of the CPU matches a known signature, then we use the name,
// otherwise we encode the signature as a string so we can easily identify when
// new signatures start to become popular.
std::string getBoardName(int signature) {
  // This function will only be run once per system boot, so this map will only
  // be created once.
  static const std::map<int, std::string> knownCPUSignatures = {
      {0x806e9, "Eve"},
  };

  auto name = knownCPUSignatures.find(signature);
  if (name == knownCPUSignatures.end()) {
    char sigstr[20];  // NOLINT readability-magic-numbers
    snprintf(sigstr, sizeof(sigstr), "unknown:0x%X", signature);
    return sigstr;
  }

  return name->second;
}

// Invokes the cpuid instruction on X86. |info_type| specifies which query
// we are performing. This is written into register EAX prior to invoking
// cpuid. (The sub-type specifier in register ECX is alwyas set to zero.)  The
// results from registers EAX, EBX, ECX, EDX respectively are writtent into the
// four entries of |cpu_info|. See for example the wikipedia article on
// cpuid for more info.
void Cpuid(int info_type,
           int cpu_info[4]) {  // NOLINT readability-non-const-parameter
  __asm__ volatile("cpuid\n"
                   : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
                   : "a"(info_type), "c"(0));
}

// Invokes Cpuid() to determine the board_name.
void PopulateBoardName(SystemProfile* profile) {
  // "": means that the calling system has no idea.
  // "pc": is the current placeholder value that fuchsia reports for x86
  //       devices, so we think we can do better.
  // Anything else is considered to be "better" than just raw Cpuid or a lookup
  // table.
  if (profile->board_name().empty() || profile->board_name() == "pc") {
    // First we invoke Cpuid with info_type = 0 in order to obtain num_ids
    // and vendor_name.
    int cpu_info[4] = {-1};
    Cpuid(0, cpu_info);
    int num_ids = cpu_info[0];

    if (num_ids > 0) {
      // Then invoke Cpuid again with info_type = 1 in order to obtain
      // |signature|.
      Cpuid(1, cpu_info);
      profile->set_board_name(getBoardName(cpu_info[0]));
    }
  }
}

#elif defined(__aarch64__)

void PopulateBoardName(SystemProfile* profile) {
  if (profile->board_name() == "") {
    profile->set_board_name("Generic ARM");
  }
}

#else

void PopulateBoardName(SystemProfile* profile) {}

#endif

}  // namespace

SystemData::SystemData(const std::string& product_name, const std::string& board_name_suggestion,
                       ReleaseStage release_stage, const std::string& version)
    : internal_metrics_(logger::InternalMetrics::NewWithLogger(nullptr)),
      release_stage_(release_stage) {
  system_profile_.set_product_name(product_name);
  system_profile_.set_board_name(board_name_suggestion);
  system_profile_.set_system_version(version);
  system_profile_.set_realm("<unset>");
  system_profile_.set_channel("<unset>");
  PopulateSystemProfile();
}

void SystemData::SetChannel(const std::string& channel) {
  system_profile_.set_channel(channel);
  NotifyChange();
}

void SystemData::SetRealm(const std::string& realm) {
  system_profile_.set_realm(realm);
  NotifyChange();
}

void SystemData::SetSoftwareDistributionInfo(SoftwareDistributionInfo info) {
  using EventCode = logger::SetSoftwareDistributionInfoCalledMetricDimensionPreviousChannel;
  logger::SetSoftwareDistributionInfoCalledEventCodes event_codes;

  if (system_profile_.channel() == "<unset>") {
    event_codes.previous_channel = EventCode::Unset;
  } else if (system_profile_.channel() == "<unknown>") {
    event_codes.previous_channel = EventCode::Unknown;
  } else {
    event_codes.previous_channel = EventCode::Valid;
  }

  if (system_profile_.realm() == "<unset>") {
    event_codes.previous_realm = EventCode::Unset;
  } else if (system_profile_.realm() == "<unknown>") {
    event_codes.previous_realm = EventCode::Unknown;
  } else {
    event_codes.previous_realm = EventCode::Valid;
  }

  event_codes.new_channel = EventCode::Unset;
  if (info.channel) {
    if (info.channel.value().empty()) {
      system_profile_.set_channel("<unknown>");
      event_codes.new_channel = EventCode::Unknown;
    } else {
      system_profile_.set_channel(info.channel.value());
      event_codes.new_channel = EventCode::Valid;
    }
  }

  event_codes.new_realm = EventCode::Unset;
  if (info.realm) {
    if (info.realm.value().empty()) {
      system_profile_.set_realm("<unknown>");
      event_codes.new_realm = EventCode::Unknown;
    } else {
      system_profile_.set_realm(info.realm.value());
      event_codes.new_realm = EventCode::Valid;
    }
  }

  internal_metrics_->SetSoftwareDistributionInfoCalled(event_codes);
  NotifyChange();
}

void SystemData::OverrideSystemProfile(const SystemProfile& profile) {
  system_profile_ = profile;
  NotifyChange();
}

void SystemData::ResetInternalMetrics(logger::LoggerInterface* internal_logger) {
  internal_metrics_ = logger::InternalMetrics::NewWithLogger(internal_logger);
};

void SystemData::OnChange(std::function<void()> callback) {
  change_callbacks_.push_back(std::move(callback));
}

void SystemData::NotifyChange() {
  for (const auto& callback : change_callbacks_) {
    callback();
  }
}

void SystemData::PopulateSystemProfile() {
#if defined(__ANDROID__)

  system_profile_.set_os(SystemProfile::ANDROID);

#elif defined(__linux__)

  system_profile_.set_os(SystemProfile::LINUX);

#elif defined(__Fuchsia__)

  system_profile_.set_os(SystemProfile::FUCHSIA);

#else

  system_profile_.set_os(SystemProfile::UNKNOWN_OS);

#endif

#if defined(__x86_64__)

  system_profile_.set_arch(SystemProfile::X86_64);

#elif defined(__aarch64__)

  system_profile_.set_arch(SystemProfile::ARM_64);

#else

  system_profile_.set_arch(SystemProfile::UNKNOWN_ARCH);

#endif

  PopulateBoardName(&system_profile_);
}

}  // namespace cobalt::system_data
