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

// 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

// TODO(fxbug.dev/85571): NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
SystemData::SystemData(const std::string& product_name, const std::string& board_name_suggestion,
                       ReleaseStage release_stage, const std::string& version,
                       SystemProfile::BuildType build_type,
                       const std::vector<ExperimentToken>& experiment_tokens,
                       const std::vector<int64_t>& experiment_ids)
    : 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>");

  for (const auto& experiment_token : experiment_tokens) {
    system_profile_.add_experiment_tokens()->CopyFrom(experiment_token);
  }

  for (const auto& experiment_id : experiment_ids) {
    system_profile_.add_experiment_ids(experiment_id);
  }

  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::SetSoftwareDistributionInfoCalledMigratedMetricDimensionPreviousChannel;
  logger::SetSoftwareDistributionInfoCalledMigratedEventCodes 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
