// Copyright 2017 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 <fidl/fuchsia.buildinfo/cpp/fidl.h>
#include <fidl/fuchsia.hwinfo/cpp/fidl.h>
#include <sys/statvfs.h>
#include <zircon/syscalls.h>

#include <string>

#include "base/containers/flat_map.h"
#include "base/files/file_util.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/system_info.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/notimplemented.h"
#include "base/numerics/clamped_math.h"
#include "base/synchronization/lock.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h"

namespace base {

namespace {

bool GetDiskSpaceInfo(const FilePath& path,
                      int64_t* available_bytes,
                      int64_t* total_bytes) {
  struct statvfs stats;
  if (statvfs(path.value().c_str(), &stats) != 0) {
    PLOG(ERROR) << "statvfs() for path:" << path;
    return false;
  }

  if (available_bytes) {
    ClampedNumeric<int64_t> available_blocks(stats.f_bavail);
    *available_bytes = available_blocks * stats.f_frsize;
  }

  if (total_bytes) {
    ClampedNumeric<int64_t> total_blocks(stats.f_blocks);
    *total_bytes = total_blocks * stats.f_frsize;
  }

  return true;
}

struct TotalDiskSpace {
  Lock lock;
  flat_map<FilePath, int64_t> space_map GUARDED_BY(lock);
};

TotalDiskSpace& GetTotalDiskSpace() {
  static NoDestructor<TotalDiskSpace> total_disk_space;
  return *total_disk_space;
}

// Returns the total-disk-space set for the volume containing |path|. If
// |volume_path| is non-null then it receives the path to the relevant volume.
// Returns -1, and does not modify |volume_path|, if no match is found. Also
// returns -1 if |path| is not absolute.
int64_t GetAmountOfTotalDiskSpaceAndVolumePath(const FilePath& path,
                                               FilePath* volume_path) {
  if (!path.IsAbsolute()) {
    return -1;
  }
  TotalDiskSpace& total_disk_space = GetTotalDiskSpace();

  AutoLock l(total_disk_space.lock);
  int64_t result = -1;
  FilePath matched_path;
  for (const auto& path_and_size : total_disk_space.space_map) {
    if (path_and_size.first == path || path_and_size.first.IsParent(path)) {
      // If a deeper path was already matched then ignore this entry.
      if (!matched_path.empty() &&
          !matched_path.IsParent(path_and_size.first)) {
        continue;
      }
      matched_path = path_and_size.first;
      result = path_and_size.second;
    }
  }

  if (volume_path) {
    *volume_path = matched_path;
  }
  return result;
}

}  // namespace

// static
ByteCount SysInfo::AmountOfPhysicalMemoryImpl() {
  return ByteCount::FromUnsigned(zx_system_get_physmem());
}

// static
ByteCount SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
  // TODO(crbug.com/42050649): Implement this when Fuchsia supports it.
  NOTIMPLEMENTED_LOG_ONCE();
  return ByteCount(0);
}

// static
int SysInfo::NumberOfProcessors() {
  return static_cast<int>(zx_system_get_num_cpus());
}

// static
uint64_t SysInfo::AmountOfVirtualMemory() {
  // Fuchsia does not provide this type of information.
  // Return zero to indicate that there is unlimited available virtual memory.
  return 0;
}

// static
std::string SysInfo::OperatingSystemName() {
  return "Fuchsia";
}

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

  // First check whether there is a soft-quota that applies to |path|.
  FilePath volume_path;
  const int64_t total_space =
      GetAmountOfTotalDiskSpaceAndVolumePath(path, &volume_path);
  if (total_space >= 0) {
    // TODO(crbug.com/42050202): Replace this with an efficient implementation.
    const int64_t used_space = ComputeDirectorySize(volume_path);
    return std::max(0l, total_space - used_space);
  }

  // Report the actual amount of free space in |path|'s filesystem.
  int64_t available;
  if (GetDiskSpaceInfo(path, &available, nullptr)) {
    return available;
  }

  return -1;
}

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

  if (path.empty()) {
    return -1;
  }

  // Return the soft-quota that applies to |path|, if one is configured.
  int64_t total_space = GetAmountOfTotalDiskSpaceAndVolumePath(path, nullptr);
  if (total_space >= 0) {
    return total_space;
  }

  // Report the actual space in |path|'s filesystem.
  if (GetDiskSpaceInfo(path, nullptr, &total_space)) {
    return total_space;
  }

  return -1;
}

// static
void SysInfo::SetAmountOfTotalDiskSpace(const FilePath& path, int64_t bytes) {
  DCHECK(path.IsAbsolute());
  TotalDiskSpace& total_disk_space = GetTotalDiskSpace();
  AutoLock l(total_disk_space.lock);
  if (bytes >= 0) {
    total_disk_space.space_map[path] = bytes;
  } else {
    total_disk_space.space_map.erase(path);
  }
}

// static
std::string SysInfo::OperatingSystemVersion() {
  const auto& build_info = GetCachedBuildInfo();
  return build_info.version().value_or("");
}

// static
void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
                                            int32_t* minor_version,
                                            int32_t* bugfix_version) {
  // TODO(crbug.com/42050501): Implement this when Fuchsia supports it.
  NOTIMPLEMENTED_LOG_ONCE();
  *major_version = 0;
  *minor_version = 0;
  *bugfix_version = 0;
}

// static
std::string SysInfo::OperatingSystemArchitecture() {
#if defined(ARCH_CPU_X86_64)
  return "x86_64";
#elif defined(ARCH_CPU_ARM64)
  return "aarch64";
#else
#error Unsupported architecture.
#endif
}

// static
std::string SysInfo::CPUModelName() {
  // TODO(crbug.com/40191727): Implement this when Fuchsia supports it.
  NOTIMPLEMENTED_LOG_ONCE();
  return std::string();
}

// static
size_t SysInfo::VMAllocationGranularity() {
  return static_cast<size_t>(getpagesize());
}

// static
int SysInfo::NumberOfEfficientProcessorsImpl() {
  NOTIMPLEMENTED();
  return 0;
}

SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
  const auto product_info = GetProductInfo();

  return {
      .manufacturer = product_info.manufacturer().value_or(""),
      .model = product_info.model().value_or(""),
  };
}

}  // namespace base
