// Copyright 2016 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.

#include "services/device/generic_sensor/platform_sensor_reader_win.h"

#include <Sensors.h>
#include <objbase.h>

#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/win/iunknown_impl.h"
#include "base/win/scoped_propvariant.h"
#include "services/device/generic_sensor/generic_sensor_consts.h"
#include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h"
#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
#include "ui/gfx/geometry/angle_conversions.h"

namespace device {

// Init params for the PlatformSensorReaderWin.
struct ReaderInitParams {
  // ISensorDataReport::GetSensorValue is not const, therefore, report
  // cannot be passed as const ref.
  // ISensorDataReport* report - report that contains new sensor data.
  // SensorReading* reading    - out parameter that must be populated.
  // Returns HRESULT           - S_OK on success, otherwise error code.
  using ReaderFunctor = HRESULT (*)(ISensorDataReport* report,
                                    SensorReading* reading);
  SENSOR_TYPE_ID sensor_type_id;
  ReaderFunctor reader_func;
  unsigned long min_reporting_interval_ms = 0;
};

namespace {

// Gets value from  the report for provided key.
bool GetReadingValueForProperty(REFPROPERTYKEY key,
                                ISensorDataReport* report,
                                double* value) {
  DCHECK(value);
  base::win::ScopedPropVariant variant_value;
  if (SUCCEEDED(report->GetSensorValue(key, variant_value.Receive()))) {
    if (variant_value.get().vt == VT_R8)
      *value = variant_value.get().dblVal;
    else if (variant_value.get().vt == VT_R4)
      *value = variant_value.get().fltVal;
    else
      return false;
    return true;
  }

  *value = 0;
  return false;
}

// Ambient light sensor reader initialization parameters.
std::unique_ptr<ReaderInitParams> CreateAmbientLightReaderInitParams() {
  auto params = std::make_unique<ReaderInitParams>();
  params->sensor_type_id = SENSOR_TYPE_AMBIENT_LIGHT;
  params->reader_func = [](ISensorDataReport* report, SensorReading* reading) {
    double lux = 0.0;
    if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, report,
                                    &lux)) {
      return E_FAIL;
    }
    reading->als.value = lux;
    return S_OK;
  };
  return params;
}

// Accelerometer sensor reader initialization parameters.
std::unique_ptr<ReaderInitParams> CreateAccelerometerReaderInitParams() {
  auto params = std::make_unique<ReaderInitParams>();
  params->sensor_type_id = SENSOR_TYPE_ACCELEROMETER_3D;
  params->reader_func = [](ISensorDataReport* report, SensorReading* reading) {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
    if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_X_G, report,
                                    &x) ||
        !GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_Y_G, report,
                                    &y) ||
        !GetReadingValueForProperty(SENSOR_DATA_TYPE_ACCELERATION_Z_G, report,
                                    &z)) {
      return E_FAIL;
    }

    // Windows HW sensor integration requirements specify accelerometer
    // measurements conventions such as, the accelerometer sensor must expose
    // values that are proportional and in the same direction as the force of
    // gravity. Therefore, sensor hosted by the device at rest on a leveled
    // surface while the screen is facing towards the sky, must report -1G along
    // the Z axis.
    // https://msdn.microsoft.com/en-us/library/windows/hardware/dn642102(v=vs.85).aspx
    // Change sign of values, to report 'reaction force', and convert values
    // from G/s^2 to m/s^2 units.
    reading->accel.x = -x * kMeanGravity;
    reading->accel.y = -y * kMeanGravity;
    reading->accel.z = -z * kMeanGravity;
    return S_OK;
  };
  return params;
}

// Gyroscope sensor reader initialization parameters.
std::unique_ptr<ReaderInitParams> CreateGyroscopeReaderInitParams() {
  auto params = std::make_unique<ReaderInitParams>();
  params->sensor_type_id = SENSOR_TYPE_GYROMETER_3D;
  params->reader_func = [](ISensorDataReport* report, SensorReading* reading) {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
    if (!GetReadingValueForProperty(
            SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, report,
            &x) ||
        !GetReadingValueForProperty(
            SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, report,
            &y) ||
        !GetReadingValueForProperty(
            SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, report,
            &z)) {
      return E_FAIL;
    }

    // Values are converted from degrees to radians.
    reading->gyro.x = gfx::DegToRad(x);
    reading->gyro.y = gfx::DegToRad(y);
    reading->gyro.z = gfx::DegToRad(z);
    return S_OK;
  };
  return params;
}

// Magnetometer sensor reader initialization parameters.
std::unique_ptr<ReaderInitParams> CreateMagnetometerReaderInitParams() {
  auto params = std::make_unique<ReaderInitParams>();
  params->sensor_type_id = SENSOR_TYPE_COMPASS_3D;
  params->reader_func = [](ISensorDataReport* report, SensorReading* reading) {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
    if (!GetReadingValueForProperty(
            SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_X_MILLIGAUSS, report,
            &x) ||
        !GetReadingValueForProperty(
            SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_Y_MILLIGAUSS, report,
            &y) ||
        !GetReadingValueForProperty(
            SENSOR_DATA_TYPE_MAGNETIC_FIELD_STRENGTH_Z_MILLIGAUSS, report,
            &z)) {
      return E_FAIL;
    }

    // Values are converted from Milligaus to Microtesla.
    reading->magn.x = x * kMicroteslaInMilligauss;
    reading->magn.y = y * kMicroteslaInMilligauss;
    reading->magn.z = z * kMicroteslaInMilligauss;
    return S_OK;
  };
  return params;
}

// AbsoluteOrientationEulerAngles sensor reader initialization parameters.
std::unique_ptr<ReaderInitParams>
CreateAbsoluteOrientationEulerAnglesReaderInitParams() {
  auto params = std::make_unique<ReaderInitParams>();
  params->sensor_type_id = SENSOR_TYPE_INCLINOMETER_3D;
  params->reader_func = [](ISensorDataReport* report, SensorReading* reading) {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
    if (!GetReadingValueForProperty(SENSOR_DATA_TYPE_TILT_X_DEGREES, report,
                                    &x) ||
        !GetReadingValueForProperty(SENSOR_DATA_TYPE_TILT_Y_DEGREES, report,
                                    &y) ||
        !GetReadingValueForProperty(SENSOR_DATA_TYPE_TILT_Z_DEGREES, report,
                                    &z)) {
      return E_FAIL;
    }

    reading->orientation_euler.x = x;
    reading->orientation_euler.y = y;
    reading->orientation_euler.z = z;
    return S_OK;
  };
  return params;
}

// AbsoluteOrientationQuaternion sensor reader initialization parameters.
std::unique_ptr<ReaderInitParams>
CreateAbsoluteOrientationQuaternionReaderInitParams() {
  auto params = std::make_unique<ReaderInitParams>();
  params->sensor_type_id = SENSOR_TYPE_AGGREGATED_DEVICE_ORIENTATION;
  params->reader_func = [](ISensorDataReport* report, SensorReading* reading) {
    base::win::ScopedPropVariant quat_variant;
    HRESULT hr = report->GetSensorValue(SENSOR_DATA_TYPE_QUATERNION,
                                        quat_variant.Receive());
    if (FAILED(hr) || quat_variant.get().vt != (VT_VECTOR | VT_UI1) ||
        quat_variant.get().caub.cElems < 16) {
      return E_FAIL;
    }

    float* quat = reinterpret_cast<float*>(quat_variant.get().caub.pElems);

    reading->orientation_quat.x = quat[0];  // x*sin(Theta/2)
    reading->orientation_quat.y = quat[1];  // y*sin(Theta/2)
    reading->orientation_quat.z = quat[2];  // z*sin(Theta/2)
    reading->orientation_quat.w = quat[3];  // cos(Theta/2)
    return S_OK;
  };
  return params;
}

// Creates ReaderInitParams params structure. To implement support for new
// sensor types, new switch case should be added and appropriate fields must
// be set:
// sensor_type_id - GUID of the sensor supported by Windows.
// reader_func    - Functor that is responsible to populate SensorReading from
//                  ISensorDataReport data.
std::unique_ptr<ReaderInitParams> CreateReaderInitParamsForSensor(
    mojom::SensorType type) {
  switch (type) {
    case mojom::SensorType::AMBIENT_LIGHT:
      return CreateAmbientLightReaderInitParams();
    case mojom::SensorType::ACCELEROMETER:
      return CreateAccelerometerReaderInitParams();
    case mojom::SensorType::GYROSCOPE:
      return CreateGyroscopeReaderInitParams();
    case mojom::SensorType::MAGNETOMETER:
      return CreateMagnetometerReaderInitParams();
    case mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
      return CreateAbsoluteOrientationEulerAnglesReaderInitParams();
    case mojom::SensorType::ABSOLUTE_ORIENTATION_QUATERNION:
      return CreateAbsoluteOrientationQuaternionReaderInitParams();
    default:
      NOTIMPLEMENTED();
      return nullptr;
  }
}

}  // namespace

// Class that implements ISensorEvents and IUnknown interfaces and used
// by ISensor interface to dispatch state and data change events.
class EventListener : public ISensorEvents, public base::win::IUnknownImpl {
 public:
  explicit EventListener(PlatformSensorReaderWin* platform_sensor_reader)
      : platform_sensor_reader_(platform_sensor_reader) {
    DCHECK(platform_sensor_reader_);
  }

  // IUnknown interface
  ULONG STDMETHODCALLTYPE AddRef() override { return IUnknownImpl::AddRef(); }
  ULONG STDMETHODCALLTYPE Release() override { return IUnknownImpl::Release(); }

  STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override {
    if (riid == __uuidof(ISensorEvents)) {
      *ppv = static_cast<ISensorEvents*>(this);
      AddRef();
      return S_OK;
    }
    return IUnknownImpl::QueryInterface(riid, ppv);
  }

 protected:
  ~EventListener() override = default;

  // ISensorEvents interface
  STDMETHODIMP OnEvent(ISensor*, REFGUID, IPortableDeviceValues*) override {
    return S_OK;
  }

  STDMETHODIMP OnLeave(REFSENSOR_ID sensor_id) override {
    // If event listener is active and sensor is disconnected, notify client
    // about the error.
    platform_sensor_reader_->SensorError();
    platform_sensor_reader_->StopSensor();
    return S_OK;
  }

  STDMETHODIMP OnStateChanged(ISensor* sensor, SensorState state) override {
    if (sensor == nullptr)
      return E_INVALIDARG;

    if (state != SensorState::SENSOR_STATE_READY &&
        state != SensorState::SENSOR_STATE_INITIALIZING) {
      platform_sensor_reader_->SensorError();
      platform_sensor_reader_->StopSensor();
    }
    return S_OK;
  }

  STDMETHODIMP OnDataUpdated(ISensor* sensor,
                             ISensorDataReport* report) override {
    if (sensor == nullptr || report == nullptr)
      return E_INVALIDARG;

    // To get precise timestamp, we need to get delta between timestamp
    // provided in the report and current system time. Then the delta in
    // milliseconds is substracted from current high resolution timestamp.
    SYSTEMTIME report_time;
    HRESULT hr = report->GetTimestamp(&report_time);
    if (FAILED(hr))
      return hr;

    base::TimeTicks ticks_now = base::TimeTicks::Now();
    base::Time time_now = base::Time::NowFromSystemTime();

    base::Time::Exploded exploded;
    exploded.year = report_time.wYear;
    exploded.month = report_time.wMonth;
    exploded.day_of_week = report_time.wDayOfWeek;
    exploded.day_of_month = report_time.wDay;
    exploded.hour = report_time.wHour;
    exploded.minute = report_time.wMinute;
    exploded.second = report_time.wSecond;
    exploded.millisecond = report_time.wMilliseconds;

    base::Time timestamp;
    if (!base::Time::FromUTCExploded(exploded, &timestamp))
      return E_FAIL;

    base::TimeDelta delta = time_now - timestamp;

    SensorReading reading;
    reading.raw.timestamp =
        ((ticks_now - delta) - base::TimeTicks()).InSecondsF();

    // Discard update events that have non-monotonically increasing timestamp.
    if (last_sensor_reading_.raw.timestamp > reading.timestamp())
      return E_FAIL;

    hr = platform_sensor_reader_->SensorReadingChanged(report, &reading);
    if (SUCCEEDED(hr))
      last_sensor_reading_ = reading;
    return hr;
  }

 private:
  PlatformSensorReaderWin* const platform_sensor_reader_;
  SensorReading last_sensor_reading_;

  DISALLOW_COPY_AND_ASSIGN(EventListener);
};

// static
std::unique_ptr<PlatformSensorReaderWin> PlatformSensorReaderWin::Create(
    mojom::SensorType type,
    Microsoft::WRL::ComPtr<ISensorManager> sensor_manager) {
  DCHECK(sensor_manager);

  auto params = CreateReaderInitParamsForSensor(type);
  if (!params)
    return nullptr;

  auto sensor = GetSensorForType(params->sensor_type_id, sensor_manager);
  if (!sensor)
    return nullptr;

  base::win::ScopedPropVariant min_interval;
  HRESULT hr = sensor->GetProperty(SENSOR_PROPERTY_MIN_REPORT_INTERVAL,
                                   min_interval.Receive());
  if (SUCCEEDED(hr) && min_interval.get().vt == VT_UI4)
    params->min_reporting_interval_ms = min_interval.get().ulVal;

  GUID interests[] = {SENSOR_EVENT_STATE_CHANGED, SENSOR_EVENT_DATA_UPDATED};
  hr = sensor->SetEventInterest(interests, arraysize(interests));
  if (FAILED(hr))
    return nullptr;

  return base::WrapUnique(
      new PlatformSensorReaderWin(sensor, std::move(params)));
}

// static
Microsoft::WRL::ComPtr<ISensor> PlatformSensorReaderWin::GetSensorForType(
    REFSENSOR_TYPE_ID sensor_type,
    Microsoft::WRL::ComPtr<ISensorManager> sensor_manager) {
  Microsoft::WRL::ComPtr<ISensor> sensor;
  Microsoft::WRL::ComPtr<ISensorCollection> sensor_collection;
  HRESULT hr = sensor_manager->GetSensorsByType(
      sensor_type, sensor_collection.GetAddressOf());
  if (FAILED(hr) || !sensor_collection)
    return sensor;

  ULONG count = 0;
  hr = sensor_collection->GetCount(&count);
  if (SUCCEEDED(hr) && count > 0)
    sensor_collection->GetAt(0, sensor.GetAddressOf());
  return sensor;
}

PlatformSensorReaderWin::PlatformSensorReaderWin(
    Microsoft::WRL::ComPtr<ISensor> sensor,
    std::unique_ptr<ReaderInitParams> params)
    : init_params_(std::move(params)),
      task_runner_(base::ThreadTaskRunnerHandle::Get()),
      sensor_active_(false),
      client_(nullptr),
      sensor_(sensor),
      event_listener_(new EventListener(this)),
      weak_factory_(this) {
  DCHECK(init_params_);
  DCHECK(init_params_->reader_func);
  DCHECK(sensor_);
}

void PlatformSensorReaderWin::SetClient(Client* client) {
  base::AutoLock autolock(lock_);
  // Can be null.
  client_ = client;
}

void PlatformSensorReaderWin::StopSensor() {
  base::AutoLock autolock(lock_);
  if (sensor_active_) {
    sensor_->SetEventSink(nullptr);
    sensor_active_ = false;
  }
}

PlatformSensorReaderWin::~PlatformSensorReaderWin() {
  DCHECK(task_runner_->BelongsToCurrentThread());
}

bool PlatformSensorReaderWin::StartSensor(
    const PlatformSensorConfiguration& configuration) {
  base::AutoLock autolock(lock_);

  if (!SetReportingInterval(configuration))
    return false;

  if (!sensor_active_) {
    task_runner_->PostTask(
        FROM_HERE, base::Bind(&PlatformSensorReaderWin::ListenSensorEvent,
                              weak_factory_.GetWeakPtr()));
    sensor_active_ = true;
  }

  return true;
}

void PlatformSensorReaderWin::ListenSensorEvent() {
  // Set event listener.
  if (FAILED(sensor_->SetEventSink(event_listener_.get()))) {
    SensorError();
    StopSensor();
  }
}

bool PlatformSensorReaderWin::SetReportingInterval(
    const PlatformSensorConfiguration& configuration) {
  Microsoft::WRL::ComPtr<IPortableDeviceValues> props;
  if (SUCCEEDED(::CoCreateInstance(CLSID_PortableDeviceValues, nullptr,
                                   CLSCTX_ALL, IID_PPV_ARGS(&props)))) {
    unsigned interval =
        (1 / configuration.frequency()) * base::Time::kMillisecondsPerSecond;

    HRESULT hr = props->SetUnsignedIntegerValue(
        SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, interval);

    if (SUCCEEDED(hr)) {
      Microsoft::WRL::ComPtr<IPortableDeviceValues> return_props;
      hr = sensor_->SetProperties(props.Get(), return_props.GetAddressOf());
      return SUCCEEDED(hr);
    }
  }
  return false;
}

HRESULT PlatformSensorReaderWin::SensorReadingChanged(
    ISensorDataReport* report,
    SensorReading* reading) const {
  if (!client_)
    return E_FAIL;

  HRESULT hr = init_params_->reader_func(report, reading);
  if (SUCCEEDED(hr))
    client_->OnReadingUpdated(*reading);
  return hr;
}

void PlatformSensorReaderWin::SensorError() {
  if (client_)
    client_->OnSensorError();
}

unsigned long PlatformSensorReaderWin::GetMinimalReportingIntervalMs() const {
  return init_params_->min_reporting_interval_ms;
}

}  // namespace device
