// 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__) || defined(__arm__)

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,
                       SystemProfile::BuildType build_type)
    : 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_build_type(build_type);
  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::InternalMetrics* internal_metrics) {
  internal_metrics_.reset(internal_metrics);
};

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(__i386__)

  system_profile_.set_arch(SystemProfile::X86_32);
#elif defined(__aarch64__)

  system_profile_.set_arch(SystemProfile::ARM_64);

#elif defined(__arm__)

  system_profile_.set_arch(SystemProfile::ARM_32);

#else

  system_profile_.set_arch(SystemProfile::UNKNOWN_ARCH);

#endif

  PopulateBoardName(&system_profile_);
}

}  // namespace cobalt::system_data
