// Copyright 2017 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "snapshot/linux/system_snapshot_linux.h"

#include <stddef.h>
#include <sys/types.h>
#include <sys/utsname.h>

#include <algorithm>

#include "base/check_op.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "snapshot/cpu_context.h"
#include "snapshot/posix/timezone.h"
#include "util/file/file_io.h"
#include "util/numeric/in_range_cast.h"
#include "util/string/split_string.h"

#if BUILDFLAG(IS_ANDROID)
#include <sys/system_properties.h>
#endif

namespace crashpad {
namespace internal {

namespace {

bool ReadCPUsOnline(uint32_t* first_cpu, uint8_t* cpu_count) {
  std::string contents;
  if (!LoggingReadEntireFile(base::FilePath("/sys/devices/system/cpu/online"),
                             &contents)) {
    return false;
  }
  if (contents.back() != '\n') {
    LOG(ERROR) << "format error";
    return false;
  }
  contents.pop_back();

  unsigned int count = 0;
  unsigned int first = 0;
  bool have_first = false;
  std::vector<std::string> ranges = SplitString(contents, ',');
  for (const auto& range : ranges) {
    std::string left, right;
    if (SplitStringFirst(range, '-', &left, &right)) {
      unsigned int start, end;
      if (!base::StringToUint(base::StringPiece(left), &start) ||
          !base::StringToUint(base::StringPiece(right), &end) || end <= start) {
        LOG(ERROR) << "format error: " << range;
        return false;
      }
      if (end <= start) {
        LOG(ERROR) << "format error";
        return false;
      }
      count += end - start + 1;
      if (!have_first) {
        first = start;
        have_first = true;
      }
    } else {
      unsigned int cpuno;
      if (!base::StringToUint(base::StringPiece(range), &cpuno)) {
        LOG(ERROR) << "format error";
        return false;
      }
      if (!have_first) {
        first = cpuno;
        have_first = true;
      }
      ++count;
    }
  }
  if (!have_first) {
    LOG(ERROR) << "no cpus online";
    return false;
  }
  *cpu_count = InRangeCast<uint8_t>(count, std::numeric_limits<uint8_t>::max());
  *first_cpu = first;
  return true;
}

bool ReadFreqFile(const std::string& filename, uint64_t* hz) {
  std::string contents;
  if (!LoggingReadEntireFile(base::FilePath(filename), &contents)) {
    return false;
  }
  if (contents.back() != '\n') {
    LOG(ERROR) << "format error";
    return false;
  }
  contents.pop_back();

  uint64_t khz;
  if (!base::StringToUint64(base::StringPiece(contents), &khz)) {
    LOG(ERROR) << "format error";
    return false;
  }

  *hz = khz * 1000;
  return true;
}

#if BUILDFLAG(IS_ANDROID)
bool ReadProperty(const char* property, std::string* value) {
  char value_buffer[PROP_VALUE_MAX];
  int length = __system_property_get(property, value_buffer);
  if (length <= 0) {
    LOG(ERROR) << "Couldn't read property " << property;
    return false;
  }
  *value = value_buffer;
  return true;
}
#endif  // BUILDFLAG(IS_ANDROID)

}  // namespace

SystemSnapshotLinux::SystemSnapshotLinux()
    : SystemSnapshot(),
      os_version_full_(),
      os_version_build_(),
      process_reader_(nullptr),
      snapshot_time_(nullptr),
#if defined(ARCH_CPU_X86_FAMILY)
      cpuid_(),
#endif  // ARCH_CPU_X86_FAMILY
      os_version_major_(-1),
      os_version_minor_(-1),
      os_version_bugfix_(-1),
      target_cpu_(0),
      cpu_count_(0),
      initialized_() {
}

SystemSnapshotLinux::~SystemSnapshotLinux() {}

void SystemSnapshotLinux::Initialize(ProcessReaderLinux* process_reader,
                                     const timeval* snapshot_time) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
  process_reader_ = process_reader;
  snapshot_time_ = snapshot_time;

#if BUILDFLAG(IS_ANDROID)
  std::string build_string;
  if (ReadProperty("ro.build.fingerprint", &build_string)) {
    os_version_build_ = build_string;
    os_version_full_ = build_string;
  }
#endif  // BUILDFLAG(IS_ANDROID)

  utsname uts;
  if (uname(&uts) != 0) {
    PLOG(WARNING) << "uname";
  } else {
    if (!os_version_full_.empty()) {
      os_version_full_.push_back(' ');
    }
    os_version_full_ += base::StringPrintf(
        "%s %s %s %s", uts.sysname, uts.release, uts.version, uts.machine);
  }
  ReadKernelVersion(uts.release);

  if (!os_version_build_.empty()) {
    os_version_build_.push_back(' ');
  }
  os_version_build_ += uts.version;
  os_version_build_.push_back(' ');
  os_version_build_ += uts.machine;

  if (!ReadCPUsOnline(&target_cpu_, &cpu_count_)) {
    target_cpu_ = 0;
    cpu_count_ = 0;
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
}

CPUArchitecture SystemSnapshotLinux::GetCPUArchitecture() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return process_reader_->Is64Bit() ? kCPUArchitectureX86_64
                                    : kCPUArchitectureX86;
#elif defined(ARCH_CPU_ARM_FAMILY)
  return process_reader_->Is64Bit() ? kCPUArchitectureARM64
                                    : kCPUArchitectureARM;
#elif defined(ARCH_CPU_MIPS_FAMILY)
  return process_reader_->Is64Bit() ? kCPUArchitectureMIPS64EL
                                    : kCPUArchitectureMIPSEL;
#elif defined(ARCH_CPU_RISCV64)
  return kCPUArchitectureRISCV64;
#else
#error port to your architecture
#endif
}

uint32_t SystemSnapshotLinux::CPURevision() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.Revision();
#elif defined(ARCH_CPU_ARM_FAMILY)
  // TODO(jperaza): do this. https://crashpad.chromium.org/bug/30
  return 0;
#elif defined(ARCH_CPU_MIPS_FAMILY)
  // Not implementable on MIPS
  return 0;
#elif defined(ARCH_CPU_RISCV64)
  // Not implemented
  return 0;
#else
#error port to your architecture
#endif
}

uint8_t SystemSnapshotLinux::CPUCount() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return cpu_count_;
}

std::string SystemSnapshotLinux::CPUVendor() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.Vendor();
#elif defined(ARCH_CPU_ARM_FAMILY)
  // TODO(jperaza): do this. https://crashpad.chromium.org/bug/30
  return std::string();
#elif defined(ARCH_CPU_MIPS_FAMILY)
  // Not implementable on MIPS
  return std::string();
#elif defined(ARCH_CPU_RISCV64)
  // Not implemented
  return std::string();
#else
#error port to your architecture
#endif
}

void SystemSnapshotLinux::CPUFrequency(uint64_t* current_hz,
                                       uint64_t* max_hz) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  *current_hz = 0;
  *max_hz = 0;

  ReadFreqFile(base::StringPrintf(
                   "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq",
                   target_cpu_),
               current_hz);

  ReadFreqFile(base::StringPrintf(
                   "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq",
                   target_cpu_),
               max_hz);
}

uint32_t SystemSnapshotLinux::CPUX86Signature() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.Signature();
#else
  NOTREACHED();
#endif
}

uint64_t SystemSnapshotLinux::CPUX86Features() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.Features();
#else
  NOTREACHED();
#endif
}

uint64_t SystemSnapshotLinux::CPUX86ExtendedFeatures() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.ExtendedFeatures();
#else
  NOTREACHED();
#endif
}

uint32_t SystemSnapshotLinux::CPUX86Leaf7Features() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.Leaf7Features();
#else
  NOTREACHED();
#endif
}

bool SystemSnapshotLinux::CPUX86SupportsDAZ() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.SupportsDAZ();
#else
  NOTREACHED();
#endif  // ARCH_CPU_X86_FMAILY
}

SystemSnapshot::OperatingSystem SystemSnapshotLinux::GetOperatingSystem()
    const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if BUILDFLAG(IS_ANDROID)
  return kOperatingSystemAndroid;
#else
  return kOperatingSystemLinux;
#endif  // BUILDFLAG(IS_ANDROID)
}

bool SystemSnapshotLinux::OSServer() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return false;
}

void SystemSnapshotLinux::OSVersion(int* major,
                                    int* minor,
                                    int* bugfix,
                                    std::string* build) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  *major = os_version_major_;
  *minor = os_version_minor_;
  *bugfix = os_version_bugfix_;
  build->assign(os_version_build_);
}

std::string SystemSnapshotLinux::OSVersionFull() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return os_version_full_;
}

std::string SystemSnapshotLinux::MachineDescription() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if BUILDFLAG(IS_ANDROID)
  std::string description;
  std::string prop;
  if (ReadProperty("ro.product.model", &prop)) {
    description += prop;
  }
  if (ReadProperty("ro.product.board", &prop)) {
    if (!description.empty()) {
      description.push_back(' ');
    }
    description += prop;
  }
  return description;
#else
  return std::string();
#endif  // BUILDFLAG(IS_ANDROID)
}

bool SystemSnapshotLinux::NXEnabled() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_FAMILY)
  return cpuid_.NXEnabled();
#elif defined(ARCH_CPU_ARM_FAMILY)
  // TODO(jperaza): do this. https://crashpad.chromium.org/bug/30
  return false;
#elif defined(ARCH_CPU_MIPS_FAMILY)
  // Not implementable on MIPS
  return false;
#elif defined(ARCH_CPU_RISCV64)
  // Not implemented
  return false;
#else
#error Port.
#endif  // ARCH_CPU_X86_FAMILY
}

void SystemSnapshotLinux::TimeZone(DaylightSavingTimeStatus* dst_status,
                                   int* standard_offset_seconds,
                                   int* daylight_offset_seconds,
                                   std::string* standard_name,
                                   std::string* daylight_name) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  internal::TimeZone(*snapshot_time_,
                     dst_status,
                     standard_offset_seconds,
                     daylight_offset_seconds,
                     standard_name,
                     daylight_name);
}

void SystemSnapshotLinux::ReadKernelVersion(const std::string& version_string) {
  std::vector<std::string> versions = SplitString(version_string, '.');
  if (versions.size() < 3) {
    LOG(WARNING) << "format error";
    return;
  }

  if (!base::StringToInt(base::StringPiece(versions[0]), &os_version_major_)) {
    LOG(WARNING) << "no kernel version";
    return;
  }
  DCHECK_GE(os_version_major_, 3);

  if (!base::StringToInt(base::StringPiece(versions[1]), &os_version_minor_)) {
    LOG(WARNING) << "no major revision";
    return;
  }
  DCHECK_GE(os_version_minor_, 0);

  size_t minor_rev_end = versions[2].find_first_not_of("0123456789");
  if (minor_rev_end == std::string::npos) {
    minor_rev_end = versions[2].size();
  }
  if (!base::StringToInt(base::StringPiece(versions[2].c_str(), minor_rev_end),
                         &os_version_bugfix_)) {
    LOG(WARNING) << "no minor revision";
    return;
  }
  DCHECK_GE(os_version_bugfix_, 0);

  if (!os_version_build_.empty()) {
    os_version_build_.push_back(' ');
  }
  os_version_build_ += versions[2].substr(minor_rev_end);
}

}  // namespace internal
}  // namespace crashpad
