// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/system/sys_info.h"

#include <stddef.h>
#include <stdint.h>
#include <windows.h>

#include <algorithm>
#include <bit>
#include <limits>
#include <type_traits>
#include <vector>

#include "base/check.h"
#include "base/containers/stack_container.h"
#include "base/files/file_path.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/process_metrics.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"

namespace {

// Returns the power efficiency levels of physical cores or empty vector on
// failure. The BYTE value of the element is the relative efficiency rank among
// all physical cores, where 0 is the most efficient, 1 is the second most
// efficient, and so on.
std::vector<BYTE> GetCoreEfficiencyClasses() {
  const DWORD kReservedSize =
      sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) * 64;
  base::StackVector<BYTE, kReservedSize> buffer;
  buffer->resize(kReservedSize);
  DWORD byte_length = kReservedSize;
  if (!GetLogicalProcessorInformationEx(
          RelationProcessorCore,
          reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*>(
              buffer->data()),
          &byte_length)) {
    DPCHECK(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
    buffer->resize(byte_length);
    if (!GetLogicalProcessorInformationEx(
            RelationProcessorCore,
            reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*>(
                buffer->data()),
            &byte_length)) {
      return {};
    }
  }

  std::vector<BYTE> efficiency_classes;
  BYTE* byte_ptr = buffer->data();
  while (byte_ptr < buffer->data() + byte_length) {
    const auto* structure_ptr =
        reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*>(byte_ptr);
    DCHECK_EQ(structure_ptr->Relationship, RelationProcessorCore);
    DCHECK_LE(&structure_ptr->Processor.EfficiencyClass +
                  sizeof(structure_ptr->Processor.EfficiencyClass),
              buffer->data() + byte_length);
    efficiency_classes.push_back(structure_ptr->Processor.EfficiencyClass);
    DCHECK_GE(
        structure_ptr->Size,
        offsetof(std::remove_pointer_t<decltype(structure_ptr)>, Processor) +
            sizeof(structure_ptr->Processor));
    byte_ptr = byte_ptr + structure_ptr->Size;
  }

  return efficiency_classes;
}

// Returns the physical cores to logical processor mapping masks by using the
// Windows API GetLogicalProcessorInformation(), or an empty vector on failure.
// When succeeded, the vector would be of same size to the number of physical
// cores, while each element is the bitmask of the logical processors that the
// physical core has.
std::vector<uint64_t> GetCoreProcessorMasks() {
  const DWORD kReservedSize = 64;
  base::StackVector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION, kReservedSize> buffer;
  buffer->resize(kReservedSize);
  DWORD byte_length = sizeof(buffer[0]) * kReservedSize;
  const BOOL result =
      GetLogicalProcessorInformation(buffer->data(), &byte_length);
  DWORD element_count = byte_length / sizeof(buffer[0]);
  DCHECK_EQ(byte_length % sizeof(buffer[0]), 0u);
  if (!result) {
    DPCHECK(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
    buffer->resize(element_count);
    if (!GetLogicalProcessorInformation(buffer->data(), &byte_length))
      return {};
  }

  std::vector<uint64_t> processor_masks;
  for (DWORD i = 0; i < element_count; i++) {
    if (buffer[i].Relationship == RelationProcessorCore) {
      processor_masks.push_back(buffer[i].ProcessorMask);
    }
  }

  return processor_masks;
}

uint64_t AmountOfMemory(DWORDLONG MEMORYSTATUSEX::*memory_field) {
  MEMORYSTATUSEX memory_info;
  memory_info.dwLength = sizeof(memory_info);
  if (!GlobalMemoryStatusEx(&memory_info)) {
    NOTREACHED();
    return 0;
  }

  return memory_info.*memory_field;
}

bool GetDiskSpaceInfo(const base::FilePath& path,
                      int64_t* available_bytes,
                      int64_t* total_bytes) {
  ULARGE_INTEGER available;
  ULARGE_INTEGER total;
  ULARGE_INTEGER free;
  if (!GetDiskFreeSpaceExW(path.value().c_str(), &available, &total, &free))
    return false;

  if (available_bytes) {
    *available_bytes = static_cast<int64_t>(available.QuadPart);
    if (*available_bytes < 0)
      *available_bytes = std::numeric_limits<int64_t>::max();
  }
  if (total_bytes) {
    *total_bytes = static_cast<int64_t>(total.QuadPart);
    if (*total_bytes < 0)
      *total_bytes = std::numeric_limits<int64_t>::max();
  }
  return true;
}

}  // namespace

namespace base {

// static
int SysInfo::NumberOfProcessors() {
  return win::OSInfo::GetInstance()->processors();
}

// static
int SysInfo::NumberOfEfficientProcessorsImpl() {
  std::vector<BYTE> efficiency_classes = GetCoreEfficiencyClasses();
  if (efficiency_classes.empty())
    return 0;

  auto [min_efficiency_class_it, max_efficiency_class_it] =
      std::minmax_element(efficiency_classes.begin(), efficiency_classes.end());
  if (*min_efficiency_class_it == *max_efficiency_class_it)
    return 0;

  std::vector<uint64_t> processor_masks = GetCoreProcessorMasks();
  if (processor_masks.empty())
    return 0;

  DCHECK_EQ(efficiency_classes.size(), processor_masks.size());
  int num_of_efficient_processors = 0;
  for (size_t i = 0; i < efficiency_classes.size(); i++) {
    if (efficiency_classes[i] == *min_efficiency_class_it) {
      num_of_efficient_processors += std::popcount(processor_masks[i]);
    }
  }

  return num_of_efficient_processors;
}

// static
uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
  return AmountOfMemory(&MEMORYSTATUSEX::ullTotalPhys);
}

// static
uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
  SystemMemoryInfoKB info;
  if (!GetSystemMemoryInfo(&info))
    return 0;
  return checked_cast<uint64_t>(info.avail_phys) * 1024;
}

// static
uint64_t SysInfo::AmountOfVirtualMemory() {
  return AmountOfMemory(&MEMORYSTATUSEX::ullTotalVirtual);
}

// static
int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  int64_t available;
  if (!GetDiskSpaceInfo(path, &available, nullptr))
    return -1;
  return available;
}

// static
int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  int64_t total;
  if (!GetDiskSpaceInfo(path, nullptr, &total))
    return -1;
  return total;
}

std::string SysInfo::OperatingSystemName() {
  return "Windows NT";
}

// static
std::string SysInfo::OperatingSystemVersion() {
  win::OSInfo* os_info = win::OSInfo::GetInstance();
  win::OSInfo::VersionNumber version_number = os_info->version_number();
  std::string version(StringPrintf("%d.%d.%d", version_number.major,
                                   version_number.minor, version_number.build));
  win::OSInfo::ServicePack service_pack = os_info->service_pack();
  if (service_pack.major != 0) {
    version += StringPrintf(" SP%d", service_pack.major);
    if (service_pack.minor != 0)
      version += StringPrintf(".%d", service_pack.minor);
  }
  return version;
}

// TODO: Implement OperatingSystemVersionComplete, which would include
// patchlevel/service pack number.
// See chrome/browser/feedback/feedback_util.h, FeedbackUtil::SetOSVersion.

// static
std::string SysInfo::OperatingSystemArchitecture() {
  win::OSInfo::WindowsArchitecture arch = win::OSInfo::GetArchitecture();
  switch (arch) {
    case win::OSInfo::X86_ARCHITECTURE:
      return "x86";
    case win::OSInfo::X64_ARCHITECTURE:
      return "x86_64";
    case win::OSInfo::IA64_ARCHITECTURE:
      return "ia64";
    case win::OSInfo::ARM64_ARCHITECTURE:
      return "arm64";
    default:
      return "";
  }
}

// static
std::string SysInfo::CPUModelName() {
  return win::OSInfo::GetInstance()->processor_model_name();
}

// static
size_t SysInfo::VMAllocationGranularity() {
  return win::OSInfo::GetInstance()->allocation_granularity();
}

// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
                                            int32_t* minor_version,
                                            int32_t* bugfix_version) {
  win::OSInfo* os_info = win::OSInfo::GetInstance();
  *major_version = static_cast<int32_t>(os_info->version_number().major);
  *minor_version = static_cast<int32_t>(os_info->version_number().minor);
  *bugfix_version = 0;
}

// static
std::string ReadHardwareInfoFromRegistry(const wchar_t* reg_value_name) {
  // On some systems or VMs, the system information and some of the below
  // locations may be missing info. Attempt to find the info from the below
  // registry keys in the order provided.
  static const wchar_t* const kSystemInfoRegKeyPaths[] = {
      L"HARDWARE\\DESCRIPTION\\System\\BIOS",
      L"SYSTEM\\CurrentControlSet\\Control\\SystemInformation",
      L"SYSTEM\\HardwareConfig\\Current",
  };

  std::wstring value;
  for (const wchar_t* system_info_reg_key_path : kSystemInfoRegKeyPaths) {
    base::win::RegKey system_information_key;
    if (system_information_key.Open(HKEY_LOCAL_MACHINE,
                                    system_info_reg_key_path,
                                    KEY_READ) == ERROR_SUCCESS) {
      if ((system_information_key.ReadValue(reg_value_name, &value) ==
           ERROR_SUCCESS) &&
          !value.empty()) {
        break;
      }
    }
  }

  return base::SysWideToUTF8(value);
}

// static
SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
  HardwareInfo info = {ReadHardwareInfoFromRegistry(L"SystemManufacturer"),
                       SysInfo::HardwareModelName()};
  return info;
}

// static
std::string SysInfo::HardwareModelName() {
  return ReadHardwareInfoFromRegistry(L"SystemProductName");
}

}  // namespace base
