// Copyright 2018 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/fuchsia/system_snapshot_fuchsia.h"

#include <zircon/syscalls.h>

#include "base/check_op.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"
#include "snapshot/posix/timezone.h"

namespace crashpad {
namespace internal {

SystemSnapshotFuchsia::SystemSnapshotFuchsia() = default;

SystemSnapshotFuchsia::~SystemSnapshotFuchsia() = default;

void SystemSnapshotFuchsia::Initialize(const timeval* snapshot_time) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  snapshot_time_ = snapshot_time;

  // This version string mirrors `uname -a` as written by
  // garnet/bin/uname/uname.c, however, this information isn't provided by
  // uname(). Additionally, uname() seems to hang if the network is in a bad
  // state when attempting to retrieve the nodename, so avoid it for now.
  std::string kernel_version = zx_system_get_version_string();

#if defined(ARCH_CPU_X86_64)
  static constexpr const char kArch[] = "x86_64";
#elif defined(ARCH_CPU_ARM64)
  static constexpr const char kArch[] = "aarch64";
#elif defined(ARCH_CPU_RISCV64)
  static constexpr const char kArch[] = "riscv64";
#else
  static constexpr const char kArch[] = "unknown";
#endif
  os_version_full_ = base::StringPrintf(
      "Zircon prerelease %s %s", kernel_version.c_str(), kArch);

  INITIALIZATION_STATE_SET_VALID(initialized_);
}

CPUArchitecture SystemSnapshotFuchsia::GetCPUArchitecture() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

#if defined(ARCH_CPU_X86_64)
  return kCPUArchitectureX86_64;
#elif defined(ARCH_CPU_ARM64)
  return kCPUArchitectureARM64;
#elif defined(ARCH_CPU_RISCV64)
  return kCPUArchitectureRISCV64;
#else
#error Port
#endif
}

uint32_t SystemSnapshotFuchsia::CPURevision() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_64)
  return cpuid_.Revision();
#else
  // TODO: https://fxbug.dev/42133257 - Read actual revision.
  return 0;
#endif
}

uint8_t SystemSnapshotFuchsia::CPUCount() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return base::saturated_cast<uint8_t>(zx_system_get_num_cpus());
}

std::string SystemSnapshotFuchsia::CPUVendor() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_64)
  return cpuid_.Vendor();
#else
  // TODO: https://fxbug.dev/42133257 - Read actual vendor.
  return std::string();
#endif
}

void SystemSnapshotFuchsia::CPUFrequency(uint64_t* current_hz,
                                         uint64_t* max_hz) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  // TODO(scottmg): https://crashpad.chromium.org/bug/196.
  *current_hz = 0;
  *max_hz = 0;
}

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

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

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

uint32_t SystemSnapshotFuchsia::CPUX86Leaf7Features() const {
#if defined(ARCH_CPU_X86_64)
  return cpuid_.Leaf7Features();
#else
  NOTREACHED();
  return 0;
#endif
}

bool SystemSnapshotFuchsia::CPUX86SupportsDAZ() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_64)
  return cpuid_.SupportsDAZ();
#else
  NOTREACHED();
  return false;
#endif
}

SystemSnapshot::OperatingSystem SystemSnapshotFuchsia::GetOperatingSystem()
    const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return kOperatingSystemFuchsia;
}

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

void SystemSnapshotFuchsia::OSVersion(int* major,
                                      int* minor,
                                      int* bugfix,
                                      std::string* build) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  // TODO(scottmg): https://crashpad.chromium.org/bug/196. There's no version
  // available to be reported yet.
  *major = 0;
  *minor = 0;
  *bugfix = 0;
  *build = std::string();
}

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

std::string SystemSnapshotFuchsia::MachineDescription() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  // TODO(scottmg): https://crashpad.chromium.org/bug/196. Not yet available,
  // upstream ZX-1775.
  return std::string();
}

bool SystemSnapshotFuchsia::NXEnabled() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
#if defined(ARCH_CPU_X86_64)
  return cpuid_.NXEnabled();
#else
  // TODO: https://fxbug.dev/42133257 - Read actual NX bit value.
  return false;
#endif
}

void SystemSnapshotFuchsia::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);
}

}  // namespace internal
}  // namespace crashpad
