/*
 * libjingle
 * Copyright 2008 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef WIN32
#include "talk/base/scoped_ptr.h"
#include "talk/base/win32.h"  // first because it brings in win32 stuff
#ifndef EXCLUDE_D3D9
#include <d3d9.h>
#endif

#elif defined(OSX)
#include <ApplicationServices/ApplicationServices.h>
#include <CoreServices/CoreServices.h>
#include <sys/sysctl.h>
#include "talk/base/macconversion.h"
#elif defined(IOS)
#include <sys/sysctl.h>
#elif defined(LINUX) || defined(ANDROID)
#include <unistd.h>
#include "talk/base/linux.h"
#endif

#include "talk/base/common.h"
#include "talk/base/cpuid.h"
#include "talk/base/logging.h"
#include "talk/base/stringutils.h"
#include "talk/base/systeminfo.h"

namespace talk_base {

// See Also: http://msdn.microsoft.com/en-us/library/ms683194(v=vs.85).aspx
#ifdef WIN32
typedef BOOL (WINAPI *LPFN_GLPI)(
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
    PDWORD);

static int NumCores() {
  // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond.
  LPFN_GLPI glpi = reinterpret_cast<LPFN_GLPI>(GetProcAddress(
      GetModuleHandle(L"kernel32"),
      "GetLogicalProcessorInformation"));
  if (NULL == glpi) {
    return -1;
  }
  // Determine buffer size, allocate and get processor information.
  // Size can change between calls (unlikely), so a loop is done.
  DWORD return_length = 0;
  scoped_array<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> infos;
  while (!glpi(infos.get(), &return_length)) {
    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
      infos.reset(new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[
          return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]);
    } else {
      return -1;
    }
  }
  int processor_core_count = 0;
  for (size_t i = 0;
      i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
    if (infos[i].Relationship == RelationProcessorCore) {
      ++processor_core_count;
    }
  }
  return processor_core_count;
}
#endif

// Note(fbarchard):
// Family and model are extended family and extended model.  8 bits each.
SystemInfo::SystemInfo()
    : physical_cpus_(1), logical_cpus_(1),
      cpu_family_(0), cpu_model_(0), cpu_stepping_(0),
      cpu_speed_(0), memory_(0) {
  // Initialize the basic information.

#if defined(__arm__)
  cpu_arch_ = ARCH_ARM;
#elif defined(CPU_X86)
  cpu_arch_ = ARCH_X86;
#else
#error "Unknown architecture."
#endif

#ifdef WIN32
  SYSTEM_INFO si;
  GetSystemInfo(&si);
  logical_cpus_ = si.dwNumberOfProcessors;
  physical_cpus_ = NumCores();
  if (physical_cpus_ <= 0) {
    physical_cpus_ = logical_cpus_;
  }
  cpu_family_ = si.wProcessorLevel;
  cpu_model_ = si.wProcessorRevision >> 8;
  cpu_stepping_ = si.wProcessorRevision & 0xFF;
#elif defined(OSX) || defined(IOS)
  uint32_t sysctl_value;
  size_t length = sizeof(sysctl_value);
  if (!sysctlbyname("hw.physicalcpu_max", &sysctl_value, &length, NULL, 0)) {
    physical_cpus_ = static_cast<int>(sysctl_value);
  }
  length = sizeof(sysctl_value);
  if (!sysctlbyname("hw.logicalcpu_max", &sysctl_value, &length, NULL, 0)) {
    logical_cpus_ = static_cast<int>(sysctl_value);
  }
  length = sizeof(sysctl_value);
  if (!sysctlbyname("machdep.cpu.family", &sysctl_value, &length, NULL, 0)) {
    cpu_family_ = static_cast<int>(sysctl_value);
  }
  length = sizeof(sysctl_value);
  if (!sysctlbyname("machdep.cpu.model", &sysctl_value, &length, NULL, 0)) {
    cpu_model_ = static_cast<int>(sysctl_value);
  }
  length = sizeof(sysctl_value);
  if (!sysctlbyname("machdep.cpu.stepping", &sysctl_value, &length, NULL, 0)) {
    cpu_stepping_ = static_cast<int>(sysctl_value);
  }
#else // LINUX || ANDROID
  ProcCpuInfo proc_info;
  if (proc_info.LoadFromSystem()) {
    proc_info.GetNumCpus(&logical_cpus_);
    proc_info.GetNumPhysicalCpus(&physical_cpus_);
    proc_info.GetCpuFamily(&cpu_family_);
#if !defined(__arm__)
    // These values aren't found on ARM systems.
    proc_info.GetSectionIntValue(0, "model", &cpu_model_);
    proc_info.GetSectionIntValue(0, "stepping", &cpu_stepping_);
    proc_info.GetSectionIntValue(0, "cpu MHz", &cpu_speed_);
#endif
  }

  // ProcCpuInfo reads cpu speed from "cpu MHz" under /proc/cpuinfo.
  // But that number is a moving target which can change on-the-fly according to
  // many factors including system workload.
  // See /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors.
  // The one in /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq is more
  // accurate. We use it as our cpu speed when it is available.
  int max_freq = talk_base::ReadCpuMaxFreq();
  if (max_freq > 0) {
    cpu_speed_ = max_freq;
  }
#endif
}

// Return the number of cpu threads available to the system.
int SystemInfo::GetMaxCpus() {
  return logical_cpus_;
}

// Return the number of cpu cores available to the system.
int SystemInfo::GetMaxPhysicalCpus() {
  return physical_cpus_;
}

// Return the number of cpus available to the process.  Since affinity can be
// changed on the fly, do not cache this value.
// Can be affected by heat.
int SystemInfo::GetCurCpus() {
  int cur_cpus;
#ifdef WIN32
  DWORD process_mask, system_mask;
  ::GetProcessAffinityMask(::GetCurrentProcess(), &process_mask, &system_mask);
  for (cur_cpus = 0; process_mask; ++cur_cpus) {
    // Sparse-ones algorithm. There are slightly faster methods out there but
    // they are unintuitive and won't make a difference on a single dword.
    process_mask &= (process_mask - 1);
  }
#elif defined(OSX)
  // Find number of _available_ cores
  cur_cpus = MPProcessorsScheduled();
#elif defined(IOS)
  uint32_t sysctl_value;
  size_t length = sizeof(sysctl_value);
  int error = sysctlbyname("hw.ncpu", &sysctl_value, &length, NULL, 0);
  cur_cpus = !error ? static_cast<int>(sysctl_value) : 1;
#else
  // Linux, Solaris, ANDROID
  cur_cpus = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
#endif
  return cur_cpus;
}

// Return the type of this CPU.
SystemInfo::Architecture SystemInfo::GetCpuArchitecture() {
  return cpu_arch_;
}

// Returns the vendor string from the cpu, e.g. "GenuineIntel", "AuthenticAMD".
// See "Intel Processor Identification and the CPUID Instruction"
// (Intel document number: 241618)
std::string SystemInfo::GetCpuVendor() {
  if (cpu_vendor_.empty()) {
    cpu_vendor_ = talk_base::CpuInfo::GetCpuVendor();
  }
  return cpu_vendor_;
}

// Return the "family" of this CPU.
int SystemInfo::GetCpuFamily() {
  return cpu_family_;
}

// Return the "model" of this CPU.
int SystemInfo::GetCpuModel() {
  return cpu_model_;
}

// Return the "stepping" of this CPU.
int SystemInfo::GetCpuStepping() {
  return cpu_stepping_;
}

// Return the clockrate of the primary processor in Mhz.  This value can be
// cached.  Returns -1 on error.
int SystemInfo::GetMaxCpuSpeed() {
  if (cpu_speed_) {
    return cpu_speed_;
  }

#ifdef WIN32
  HKEY key;
  static const WCHAR keyName[] =
      L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";

  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName , 0, KEY_QUERY_VALUE, &key)
      == ERROR_SUCCESS) {
    DWORD data, len;
    len = sizeof(data);

    if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast<LPBYTE>(&data),
                        &len) == ERROR_SUCCESS) {
      cpu_speed_ = data;
    } else {
      LOG(LS_WARNING) << "Failed to query registry value HKLM\\" << keyName
                      << "\\~Mhz";
      cpu_speed_ = -1;
    }

    RegCloseKey(key);
  } else {
    LOG(LS_WARNING) << "Failed to open registry key HKLM\\" << keyName;
    cpu_speed_ = -1;
  }
#elif defined(IOS) || defined(OSX)
  uint64_t sysctl_value;
  size_t length = sizeof(sysctl_value);
  int error = sysctlbyname("hw.cpufrequency_max", &sysctl_value, &length, NULL, 0);
  cpu_speed_ = !error ? static_cast<int>(sysctl_value/1000000) : -1;
#else
  // TODO: Implement using proc/cpuinfo
  cpu_speed_ = 0;
#endif
  return cpu_speed_;
}

// Dynamically check the current clockrate, which could be reduced because of
// powersaving profiles.  Eventually for windows we want to query WMI for
// root\WMI::ProcessorPerformance.InstanceName="Processor_Number_0".frequency
int SystemInfo::GetCurCpuSpeed() {
#ifdef WIN32
  // TODO: Add WMI check, requires COM initialization
  // NOTE(fbarchard): Testable on Sandy Bridge.
  return GetMaxCpuSpeed();
#elif defined(IOS) || defined(OSX)
  uint64_t sysctl_value;
  size_t length = sizeof(sysctl_value);
  int error = sysctlbyname("hw.cpufrequency", &sysctl_value, &length, NULL, 0);
  return !error ? static_cast<int>(sysctl_value/1000000) : GetMaxCpuSpeed();
#else // LINUX || ANDROID
  // TODO: Use proc/cpuinfo for Cur speed on Linux.
  return GetMaxCpuSpeed();
#endif
}

// Returns the amount of installed physical memory in Bytes.  Cacheable.
// Returns -1 on error.
int64 SystemInfo::GetMemorySize() {
  if (memory_) {
    return memory_;
  }

#ifdef WIN32
  MEMORYSTATUSEX status = {0};
  status.dwLength = sizeof(status);

  if (GlobalMemoryStatusEx(&status)) {
    memory_ = status.ullTotalPhys;
  } else {
    LOG_GLE(LS_WARNING) << "GlobalMemoryStatusEx failed.";
    memory_ = -1;
  }

#elif defined(OSX) || defined(IOS)
  size_t len = sizeof(memory_);
  int error = sysctlbyname("hw.memsize", &memory_, &len, NULL, 0);
  if (error || memory_ == 0) {
    memory_ = -1;
  }
#else
  memory_ = static_cast<int64>(sysconf(_SC_PHYS_PAGES)) *
      static_cast<int64>(sysconf(_SC_PAGESIZE));
  if (memory_ < 0) {
    LOG(LS_WARNING) << "sysconf(_SC_PHYS_PAGES) failed."
                    << "sysconf(_SC_PHYS_PAGES) " << sysconf(_SC_PHYS_PAGES)
                    << "sysconf(_SC_PAGESIZE) " << sysconf(_SC_PAGESIZE);
    memory_ = -1;
  }
#endif

  return memory_;
}


// Return the name of the machine model we are currently running on.
// This is a human readable string that consists of the name and version
// number of the hardware, i.e 'MacBookAir1,1'. Returns an empty string if
// model can not be determined. The string is cached for subsequent calls.
std::string SystemInfo::GetMachineModel() {
  if (!machine_model_.empty()) {
    return machine_model_;
  }

#if defined(OSX) || defined(IOS)
  char buffer[128];
  size_t length = sizeof(buffer);
  int error = sysctlbyname("hw.model", buffer, &length, NULL, 0);
  if (!error) {
    machine_model_.assign(buffer, length - 1);
  } else {
    machine_model_.clear();
  }
#else
  machine_model_ = "Not available";
#endif

  return machine_model_;
}

#ifdef OSX
// Helper functions to query IOKit for video hardware properties.
static CFTypeRef SearchForProperty(io_service_t port, CFStringRef name) {
  return IORegistryEntrySearchCFProperty(port, kIOServicePlane,
      name, kCFAllocatorDefault,
      kIORegistryIterateRecursively | kIORegistryIterateParents);
}

static void GetProperty(io_service_t port, CFStringRef name, int* value) {
  if (!value) return;
  CFTypeRef ref = SearchForProperty(port, name);
  if (ref) {
    CFTypeID refType = CFGetTypeID(ref);
    if (CFNumberGetTypeID() == refType) {
      CFNumberRef number = reinterpret_cast<CFNumberRef>(ref);
      p_convertCFNumberToInt(number, value);
    } else if (CFDataGetTypeID() == refType) {
      CFDataRef data = reinterpret_cast<CFDataRef>(ref);
      if (CFDataGetLength(data) == sizeof(UInt32)) {
        *value = *reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data));
      }
    }
    CFRelease(ref);
  }
}

static void GetProperty(io_service_t port, CFStringRef name,
                        std::string* value) {
  if (!value) return;
  CFTypeRef ref = SearchForProperty(port, name);
  if (ref) {
    CFTypeID refType = CFGetTypeID(ref);
    if (CFStringGetTypeID() == refType) {
      CFStringRef stringRef = reinterpret_cast<CFStringRef>(ref);
      p_convertHostCFStringRefToCPPString(stringRef, *value);
    } else if (CFDataGetTypeID() == refType) {
      CFDataRef dataRef = reinterpret_cast<CFDataRef>(ref);
      *value = std::string(reinterpret_cast<const char*>(
          CFDataGetBytePtr(dataRef)), CFDataGetLength(dataRef));
    }
    CFRelease(ref);
  }
}
#endif

// Fills a struct with information on the graphics adapater and returns true
// iff successful.
bool SystemInfo::GetGpuInfo(GpuInfo *info) {
  if (!info) return false;
#if defined(WIN32) && !defined(EXCLUDE_D3D9)
  D3DADAPTER_IDENTIFIER9 identifier;
  HRESULT hr = E_FAIL;
  HINSTANCE d3d_lib = LoadLibrary(L"d3d9.dll");

  if (d3d_lib) {
    typedef IDirect3D9* (WINAPI *D3DCreate9Proc)(UINT);
    D3DCreate9Proc d3d_create_proc = reinterpret_cast<D3DCreate9Proc>(
        GetProcAddress(d3d_lib, "Direct3DCreate9"));
    if (d3d_create_proc) {
      IDirect3D9* d3d = d3d_create_proc(D3D_SDK_VERSION);
      if (d3d) {
        hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
        d3d->Release();
      }
    }
    FreeLibrary(d3d_lib);
  }

  if (hr != D3D_OK) {
    LOG(LS_ERROR) << "Failed to access Direct3D9 information.";
    return false;
  }

  info->device_name = identifier.DeviceName;
  info->description = identifier.Description;
  info->vendor_id = identifier.VendorId;
  info->device_id = identifier.DeviceId;
  info->driver = identifier.Driver;
  // driver_version format: product.version.subversion.build
  std::stringstream ss;
  ss << HIWORD(identifier.DriverVersion.HighPart) << "."
     << LOWORD(identifier.DriverVersion.HighPart) << "."
     << HIWORD(identifier.DriverVersion.LowPart) << "."
     << LOWORD(identifier.DriverVersion.LowPart);
  info->driver_version = ss.str();
  return true;
#elif defined(OSX)
  // We'll query the IOKit for the gpu of the main display.
  io_service_t display_service_port = CGDisplayIOServicePort(
      kCGDirectMainDisplay);
  GetProperty(display_service_port, CFSTR("vendor-id"), &info->vendor_id);
  GetProperty(display_service_port, CFSTR("device-id"), &info->device_id);
  GetProperty(display_service_port, CFSTR("model"), &info->description);
  return true;
#else // LINUX || ANDROID
  // TODO: Implement this on Linux
  return false;
#endif
}
} // namespace talk_base
