// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file is based on the SMSLib library.
//
// SMSLib Sudden Motion Sensor Access Library
// Copyright (c) 2010 Suitable Systems
// All rights reserved.
//
// Developed by: Daniel Griscom
//               Suitable Systems
//               http://www.suitable.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal with the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimers.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the names of Suitable Systems nor the names of its
// contributors may be used to endorse or promote products derived from
// this Software without specific prior written permission.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
//
// For more information about SMSLib, see
//    <http://www.suitable.com/tools/smslib.html>
// or contact
//    Daniel Griscom
//    Suitable Systems
//    1 Centre Street, Suite 204
//    Wakefield, MA 01880
//    (781) 665-0053

#include "sudden_motion_sensor_mac.h"

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

#include <memory>

#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"

struct SuddenMotionSensor::GenericMacbookSensor {
  // Name of device to be read.
  const char* service_name;

  // Number of bytes of the axis data.
  int axis_size;

  // Default calibration value for zero g.
  float zero_g;

  // Default calibration value for one g (negative when axis is inverted).
  float one_g;

  // Kernel function index.
  unsigned int function;

  // Size of the sensor record to be sent/received.
  unsigned int record_size;
};

struct SuddenMotionSensor::AxisData {
  // Location of the first byte representing the axis in the sensor data.
  int index;

  // Axis inversion flag. The value changes often between models.
  bool inverted;
};

// Sudden Motion Sensor descriptor.
struct SuddenMotionSensor::SensorDescriptor {
  // Prefix of model to be tested.
  const char* model_name;

  // Board id of model, or nullptr if it doesn't matter.
  const char* board_id;

  // Axis-specific data (x,y,z order).
  AxisData axis[3];
};

// Typical sensor parameters in MacBook models.
const SuddenMotionSensor::GenericMacbookSensor
    SuddenMotionSensor::kGenericSensor = {
  "SMCMotionSensor", 2,
  0, 251,
  5, 40
};

// Supported sensor descriptors. Add entries here to enhance compatibility.
// Tested in order; place more specific entries before more general ones. (All
// non-tested entries from SMSLib have been removed.)
const SuddenMotionSensor::SensorDescriptor
    SuddenMotionSensor::kSupportedSensors[] = {
  // Tested by tommyw on a 13" MacBook.
  { "MacBook1,1",    nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by S.Selz. (via avi) on a 13" MacBook.
  { "MacBook2,1",    nullptr, { { 0, true  }, { 2, false }, { 4, true  } } },

  // Tested by verhees on a 13" MacBook.
  { "MacBook3,1",    nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by adlr on a 13" MacBook.
  { "MacBook4,1",    nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by thakis on a 13" MacBook.
  { "MacBook5,1",    nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by Adam Gerson (via avi) on a 13" MacBook.
  { "MacBook5,2",    nullptr, { { 0, false }, { 2, true  }, { 4, true  } } },

  // Tested by tommyw on a 13" MacBook.
  { "MacBook6,1",    nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by avi on a 13" MacBook.
  { "MacBook7,1",    nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Note:
  // - MacBook8,1 (12" MacBook, early 2015)
  // - MacBook9,1 (12" MacBook, early 2016)
  // - MacBook10,1 (12" MacBook, mid 2017)
  // have no accelerometer sensors.

  // Tested by crc on a 13" MacBook Air.
  { "MacBookAir1,1", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by sfiera, pjw on a 13" MacBook Air.
  { "MacBookAir2,1", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Note:
  // - MacBookAir3,1 (11" MacBook Air, late 2010)
  // - MacBookAir3,2 (13" MacBook Air, late 2010)
  // - MacBookAir4,1 (11" MacBook Air, mid 2011)
  // - MacBookAir4,2 (13" MacBook Air, mid 2011)
  // - MacBookAir5,1 (11" MacBook Air, mid 2012)
  // - MacBookAir5,2 (13" MacBook Air, mid 2012)
  // - MacBookAir6,1 (11" MacBook Air, mid 2013)
  // - MacBookAir6,2 (13" MacBook Air, mid 2013)
  // - MacBookAir7,1 (11" MacBook Air, early 2015)
  // - MacBookAir7,2 (13" MacBook Air, early 2015)
  // have no accelerometer sensors.

  // Tested by crc on a 15" MacBook Pro.
  { "MacBookPro1,1", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by Raul Cuza (via avi) on a 17" MacBook Pro.
  { "MacBookPro1,2", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by L.V. (via avi) on a 17" MacBook Pro.
  { "MacBookPro2,1", nullptr, { { 0, true  }, { 2, false }, { 4, true  } } },

  // Tested by leandrogracia on a 15" MacBook Pro.
  { "MacBookPro2,2", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // Tested by S.Som. (via avi) on a 17" MacBook Pro.
  { "MacBookPro3,1", "Mac-F42388C8",
                              { { 0, true  }, { 2, false }, { 4, true  } } },

  // Tested by leandrogracia on a 15" MacBook Pro.
  { "MacBookPro3,1", nullptr, { { 0, false }, { 2, true  }, { 4, true  } } },

  // Tested by leandrogracia on a 15" MacBook Pro.
  // Tested by Eric Shapiro (via avi) on a 17" MacBook Pro.
  { "MacBookPro4,1", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // MacBookPro5,1 handled by the generic case below.
  // Tested by leandrogracia on a 15" MacBook Pro.

  // MacBookPro5,2 handled by the generic case below.
  // Tested by S.Selz. (via avi) on a 17" MacBook Pro.

  // Tested by dmaclach on a 15" MacBook Pro.
  { "MacBookPro5,3", nullptr, { { 2, false }, { 0, false }, { 4, true  } } },

  // MacBookPro5,4 handled by the generic case below.
  // Tested by leandrogracia on a 15" MacBook Pro.

  // Tested by leandrogracia on a 13" MacBook Pro.
  { "MacBookPro5,5", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // MacBookPro6,1 handled by the generic case below.
  // Tested by khom, leadpipe on a 17" MacBook Pro.

  // Tested by leandrogracia on a 15" MacBook Pro.
  { "MacBookPro6,2", nullptr, { { 0, true  }, { 2, false }, { 4, true  } } },

  // Tested by leandrogracia on a 13" MacBook Pro.
  { "MacBookPro7,1", nullptr, { { 0, true  }, { 2, true  }, { 4, false } } },

  // MacBookPro8,1 handled by the generic case below.
  // Tested by avi on a 13" MacBook Pro.

  // MacBookPro8,2 handled by the generic case below.
  // Tested by avi on a 15" MacBook Pro.

  // MacBookPro8,3 handled by the generic case below.
  // Tested by avi on a 17" MacBook Pro.

  // MacBookPro9,1 handled by the generic case below.
  // Tested by avi on a 15" MacBook Pro.

  // MacBookPro9,2 handled by the generic case below.
  // Tested by avi on a 13" MacBook Pro.

  // Note:
  // - MacBookPro10,1 (15" MacBook Pro Retina, mid 2012)
  // has no accelerometer sensors.

  // MacBookPro10,2 handled by the generic case below.
  // Tested by avi on a 13" MacBook Pro with Retina display.

  // Note:
  // - MacBookPro11,1 (13" MacBook Pro, late 2013 - mid 2014)
  // - MacBookPro11,2 (15" MacBook Pro, late 2013 - mid 2014)
  // - MacBookPro11,3 (15" MacBook Pro, late 2013 - mid 2014)
  // - MacBookPro11,4 (15" MacBook Pro, mid 2015)
  // - MacBookPro11,5 (15" MacBook Pro, mid 2015)
  // - MacBookPro12,1 (13" MacBook Pro, early 2015)
  // - MacBookPro13,1 (13" MacBook Pro, late 2016)
  // - MacBookPro13,2 (13" MacBook Pro, late 2016)
  // - MacBookPro13,3 (15" MacBook Pro, late 2016)
  // - MacBookPro14,1 (13" MacBook Pro, mid 2017)
  // - MacBookPro14,2 (13" MacBook Pro, mid 2017)
  // - MacBookPro14,3 (15" MacBook Pro, mid 2017)
  // have no accelerometer sensors.

  // Generic MacBook accelerometer sensor data, to be used for future models
  // as well as models for which it is verified to be correct. Note that this
  // configuration may have problems with inverted axes when used generically
  // for untested models.
  { "",              nullptr, { { 0, false }, { 2, false }, { 4, false } } }
};

// Create a SuddenMotionSensor object and return nullptr if no valid sensor
// found.
SuddenMotionSensor* SuddenMotionSensor::Create() {
  std::unique_ptr<SuddenMotionSensor> accelerometer(new SuddenMotionSensor);
  return accelerometer->Init() ? accelerometer.release() : nullptr;
}

SuddenMotionSensor::~SuddenMotionSensor() {
  IOServiceClose(io_connection_);
}

SuddenMotionSensor::SuddenMotionSensor()
    : sensor_(nullptr),
      io_connection_(0) {
}

//  Retrieve per-axis accelerometer values.
bool SuddenMotionSensor::ReadSensorValues(float axes[3]) {
  DCHECK(sensor_);

  // Reset output record memory buffer.
  std::fill(output_record_.begin(), output_record_.end(), 0x00);

  // Read record data from memory.
  const size_t kInputSize = kGenericSensor.record_size;
  size_t output_size = kGenericSensor.record_size;

  if (IOConnectCallStructMethod(io_connection_, kGenericSensor.function,
      static_cast<const char *>(&input_record_[0]), kInputSize,
      &output_record_[0], &output_size) != KERN_SUCCESS) {
    return false;
  }

  // Calculate per-axis calibrated values.
  float axis_value[3];

  for (int i = 0; i < 3; ++i) {
    int sensor_value = 0;
    int size  = kGenericSensor.axis_size;
    int index = sensor_->axis[i].index;

    // Important Note: Little endian is assumed as this code is Mac-only
    //                 and PowerPC is currently not supported.
    memcpy(&sensor_value, &output_record_[index], size);

    sensor_value = ExtendSign(sensor_value, size);

    // Correct value using the current calibration.
    axis_value[i] = static_cast<float>(sensor_value - kGenericSensor.zero_g) /
                    kGenericSensor.one_g;

    // Make sure we reject any NaN or infinite values.
    if (!isfinite(axis_value[i]))
      return false;

    // Clamp value to the [-1, 1] range.
    if (axis_value[i] < -1.0)
      axis_value[i] = -1.0;
    else if (axis_value[i] > 1.0)
      axis_value[i] = 1.0;

    // Apply axis inversion.
    if (sensor_->axis[i].inverted)
      axis_value[i] = -axis_value[i];
  }

  axes[0] = axis_value[0];
  axes[1] = axis_value[1];
  axes[2] = axis_value[2];

  return true;
}

// Probe the local hardware looking for a supported sensor device
// and initialize an I/O connection to it.
bool SuddenMotionSensor::Init() {
  // Request model name from the kernel.
  char local_model[32];  // size from SMSLib
  size_t local_model_size = sizeof(local_model);
  int params[2] = { CTL_HW, HW_MODEL };
  if (sysctl(params, 2, local_model, &local_model_size, nullptr, 0) != 0)
    return false;

  const SensorDescriptor* sensor_candidate = nullptr;

  // Look for the current model in the supported sensor list.
  base::ScopedCFTypeRef<CFDataRef> board_id_data;
  const int kNumSensors = arraysize(kSupportedSensors);

  for (int i = 0; i < kNumSensors; ++i) {
    // Check if the supported sensor model name is a prefix
    // of the local hardware model (empty names are accepted).
    const char* p1 = kSupportedSensors[i].model_name;
    for (const char* p2 = local_model; *p1 != '\0' && *p1 == *p2; ++p1, ++p2)
      continue;
    if (*p1 != '\0')
      continue;

    // Check the board id.
    if (kSupportedSensors[i].board_id) {
      if (!board_id_data.get()) {
        CFMutableDictionaryRef dict =
            IOServiceMatching("IOPlatformExpertDevice");
        if (!dict)
          continue;

        io_service_t platform_expert =
            IOServiceGetMatchingService(kIOMasterPortDefault, dict);
        if (!platform_expert)
          continue;

        board_id_data.reset((CFDataRef)
            IORegistryEntryCreateCFProperty(platform_expert,
                                            CFSTR("board-id"),
                                            kCFAllocatorDefault,
                                            0));
        IOObjectRelease(platform_expert);
        if (!board_id_data.get())
          continue;
      }

      if (strcmp(kSupportedSensors[i].board_id,
                 (const char*)CFDataGetBytePtr(board_id_data)) != 0) {
        continue;
      }
    }

    // Local hardware found in the supported sensor list.
    sensor_candidate = &kSupportedSensors[i];

    // Get a dictionary of the services matching to the one in the sensor.
    CFMutableDictionaryRef dict =
        IOServiceMatching(kGenericSensor.service_name);
    if (!dict)
      continue;

    // Get the first matching service.
    io_service_t device = IOServiceGetMatchingService(kIOMasterPortDefault,
                                                      dict);
    if (!device)
      continue;

    // Try to open device.
    kern_return_t result;
    result = IOServiceOpen(device, mach_task_self(), 0, &io_connection_);
    IOObjectRelease(device);
    if (result != KERN_SUCCESS || io_connection_ == 0)
      return false;

    // Local sensor service confirmed by IOKit.
    sensor_ = sensor_candidate;
    break;
  }

  if (sensor_ == nullptr)
    return false;

  // Allocate and initialize input/output records.
  input_record_.resize(kGenericSensor.record_size, 0x01);
  output_record_.resize(kGenericSensor.record_size, 0x00);

  // Try to retrieve the current orientation.
  float test_axes[3];
  return ReadSensorValues(test_axes);
}

// Extend the sign of an integer of less than 32 bits to a 32-bit integer.
int SuddenMotionSensor::ExtendSign(int value, size_t size) {
  switch (size) {
  case 1:
    if (value & 0x00000080)
      return value | 0xffffff00;
    break;

  case 2:
    if (value & 0x00008000)
      return value | 0xffff0000;
    break;

  case 3:
    if (value & 0x00800000)
      return value | 0xff000000;
    break;

  default:
    LOG(FATAL) << "Invalid integer size for sign extension: " << size;
  }

  return value;
}
