// 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 <comdef.h>
#include <objbase.h>

#include <iomanip>

#include "base/memory/ptr_util.h"
#include "base/stl_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, base::size(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;
  HRESULT hr = ::CoCreateInstance(CLSID_PortableDeviceValues, nullptr,
                                  CLSCTX_ALL, IID_PPV_ARGS(&props));
  if (FAILED(hr)) {
    static bool logged_failure = false;
    if (!logged_failure) {
      LOG(ERROR) << "Unable to create instance of PortableDeviceValues: "
                 << _com_error(hr).ErrorMessage() << " (0x" << std::hex
                 << std::uppercase << std::setfill('0') << std::setw(8) << hr
                 << ")";
      logged_failure = true;
    }
    return false;
  }

  unsigned interval =
      (1 / configuration.frequency()) * base::Time::kMillisecondsPerSecond;
  hr = props->SetUnsignedIntegerValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL,
                                      interval);
  if (FAILED(hr))
    return false;

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

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
