// Copyright 2020 The Crashpad Authors. All rights reserved.
//
// 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 "util/ios/ios_system_data_collector.h"

#include <sys/sysctl.h>
#include <sys/utsname.h>

#import <Foundation/Foundation.h>
#include <TargetConditionals.h>
#import <UIKit/UIKit.h>

#include "base/mac/mach_logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "build/build_config.h"

namespace {

std::string ReadStringSysctlByName(const char* name) {
  size_t buf_len;
  if (sysctlbyname(name, nullptr, &buf_len, nullptr, 0) != 0) {
    PLOG(WARNING) << "sysctlbyname (size) " << name;
    return std::string();
  }

  if (buf_len == 0) {
    return std::string();
  }

  std::string value(buf_len - 1, '\0');
  if (sysctlbyname(name, &value[0], &buf_len, nullptr, 0) != 0) {
    PLOG(WARNING) << "sysctlbyname " << name;
    return std::string();
  }

  return value;
}

}  // namespace

namespace crashpad {

IOSSystemDataCollector::IOSSystemDataCollector()
    : major_version_(0),
      minor_version_(0),
      patch_version_(0),
      build_(),
      machine_description_(),
      orientation_(0),
      processor_count_(0),
      cpu_vendor_(),
      has_next_daylight_saving_time_(false),
      is_daylight_saving_time_(false),
      standard_offset_seconds_(0),
      daylight_offset_seconds_(0),
      standard_name_(),
      daylight_name_() {
  NSOperatingSystemVersion version =
      [[NSProcessInfo processInfo] operatingSystemVersion];
  major_version_ = base::saturated_cast<int>(version.majorVersion);
  minor_version_ = base::saturated_cast<int>(version.minorVersion);
  patch_version_ = base::saturated_cast<int>(version.patchVersion);
  processor_count_ =
      base::saturated_cast<int>([[NSProcessInfo processInfo] processorCount]);
  build_ = ReadStringSysctlByName("kern.osversion");

#if defined(ARCH_CPU_X86_64)
  cpu_vendor_ = ReadStringSysctlByName("machdep.cpu.vendor");
#endif

#if TARGET_OS_SIMULATOR
  // TODO(justincohen): Consider adding board and model information to
  // |machine_description| as well (similar to MacModelAndBoard in
  // util/mac/mac_util.cc).
  switch (UI_USER_INTERFACE_IDIOM()) {
    case UIUserInterfaceIdiomPhone:
      machine_description_ = "iOS Simulator (iPhone)";
      break;
    case UIUserInterfaceIdiomPad:
      machine_description_ = "iOS Simulator (iPad)";
      break;
    default:
      machine_description_ = "iOS Simulator (Unknown)";
      break;
  }
#elif TARGET_OS_IPHONE
  utsname uts;
  if (uname(&uts) == 0) {
    machine_description_ = uts.machine;
  }
#else
#error "Unexpected target type OS."
#endif

  InstallHandlers();
}

IOSSystemDataCollector::~IOSSystemDataCollector() {
  CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetLocalCenter(),
                                          this);
}

void IOSSystemDataCollector::OSVersion(int* major,
                                       int* minor,
                                       int* bugfix,
                                       std::string* build) const {
  *major = major_version_;
  *minor = minor_version_;
  *bugfix = patch_version_;
  build->assign(build_);
}

void IOSSystemDataCollector::InstallHandlers() {
  // Timezone.
  CFNotificationCenterAddObserver(
      CFNotificationCenterGetLocalCenter(),
      this,
      IOSSystemDataCollector::SystemTimeZoneDidChangeNotificationHandler,
      reinterpret_cast<CFStringRef>(NSSystemTimeZoneDidChangeNotification),
      nullptr,
      CFNotificationSuspensionBehaviorDeliverImmediately);
  SystemTimeZoneDidChangeNotification();

  // Orientation.
  CFNotificationCenterAddObserver(
      CFNotificationCenterGetLocalCenter(),
      this,
      IOSSystemDataCollector::OrientationDidChangeNotificationHandler,
      reinterpret_cast<CFStringRef>(UIDeviceOrientationDidChangeNotification),
      nullptr,
      CFNotificationSuspensionBehaviorDeliverImmediately);
  OrientationDidChangeNotification();
}

// static
void IOSSystemDataCollector::SystemTimeZoneDidChangeNotificationHandler(
    CFNotificationCenterRef center,
    void* observer,
    CFStringRef name,
    const void* object,
    CFDictionaryRef userInfo) {
  static_cast<IOSSystemDataCollector*>(observer)
      ->SystemTimeZoneDidChangeNotification();
}

void IOSSystemDataCollector::SystemTimeZoneDidChangeNotification() {
  NSTimeZone* time_zone = NSTimeZone.localTimeZone;
  NSDate* transition =
      [time_zone nextDaylightSavingTimeTransitionAfterDate:[NSDate date]];
  if (transition == nil) {
    has_next_daylight_saving_time_ = false;
    is_daylight_saving_time_ = false;
    standard_offset_seconds_ =
        base::saturated_cast<int>([time_zone secondsFromGMTForDate:transition]);
    standard_name_ = base::SysNSStringToUTF8([time_zone abbreviation]);
    daylight_offset_seconds_ = standard_offset_seconds_;
    daylight_name_ = standard_name_;
  } else {
    has_next_daylight_saving_time_ = true;
    is_daylight_saving_time_ = time_zone.isDaylightSavingTime;
    if (time_zone.isDaylightSavingTime) {
      standard_offset_seconds_ = base::saturated_cast<int>(
          [time_zone secondsFromGMTForDate:transition]);
      standard_name_ =
          base::SysNSStringToUTF8([time_zone abbreviationForDate:transition]);
      daylight_offset_seconds_ =
          base::saturated_cast<int>([time_zone secondsFromGMT]);
      daylight_name_ = base::SysNSStringToUTF8([time_zone abbreviation]);
    } else {
      standard_offset_seconds_ =
          base::saturated_cast<int>([time_zone secondsFromGMT]);
      standard_name_ = base::SysNSStringToUTF8([time_zone abbreviation]);
      daylight_offset_seconds_ = base::saturated_cast<int>(
          [time_zone secondsFromGMTForDate:transition]);
      daylight_name_ =
          base::SysNSStringToUTF8([time_zone abbreviationForDate:transition]);
    }
  }
}

// static
void IOSSystemDataCollector::OrientationDidChangeNotificationHandler(
    CFNotificationCenterRef center,
    void* observer,
    CFStringRef name,
    const void* object,
    CFDictionaryRef userInfo) {
  static_cast<IOSSystemDataCollector*>(observer)
      ->OrientationDidChangeNotification();
}

void IOSSystemDataCollector::OrientationDidChangeNotification() {
  orientation_ =
      base::saturated_cast<int>([[UIDevice currentDevice] orientation]);
}

}  // namespace crashpad
