// Copyright 2018 The Fuchsia 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 "garnet/bin/ui/presentation_mode/detector.h"

#include <assert.h>
#include <limits>

#include "src/lib/fxl/logging.h"

namespace presentation_mode {

Detector::Detector(size_t history_size)
    : base_accelerometer_(
          std::make_unique<internal::MovingAverage>(history_size)),
      lid_accelerometer_(
          std::make_unique<internal::MovingAverage>(history_size)) {
  FXL_CHECK(history_size > 0);
}

std::pair<bool, fuchsia::ui::policy::PresentationMode> Detector::Update(
    const fuchsia::ui::input::SensorDescriptor& sensor,
    fuchsia::ui::input::InputReport event) {
  if (sensor.type != fuchsia::ui::input::SensorType::ACCELEROMETER)
    return {false, {}};

  FXL_CHECK(event.sensor);
  FXL_CHECK(event.sensor->is_vector());

  const std::array<int16_t, 3>& vector = event.sensor->vector();
  AccelerometerData data{vector[0], vector[1], vector[2]};

  switch (sensor.loc) {
    case fuchsia::ui::input::SensorLocation::BASE:
      base_accelerometer_->Update(data);
      break;
    case fuchsia::ui::input::SensorLocation::LID:
      lid_accelerometer_->Update(data);
      break;
    default:
      break;
  }

  AccelerometerData base_avg = base_accelerometer_->Average();
  AccelerometerData lid_avg = lid_accelerometer_->Average();

  std::pair<bool, fuchsia::ui::policy::PresentationMode> result;
  result.first = false;

  if (base_avg[2] > kZPosLimit && lid_avg[2] < kZNegLimit) {
    result.first = true;
    result.second = fuchsia::ui::policy::PresentationMode::CLOSED;
  } else if (base_avg[2] > kZPosLimit && lid_avg[1] > kYPosLimit) {
    result.first = true;
    result.second = fuchsia::ui::policy::PresentationMode::LAPTOP;
  } else if (base_avg[2] < kZNegLimit && lid_avg[2] > kZPosLimit) {
    result.first = true;
    result.second = fuchsia::ui::policy::PresentationMode::TABLET;
  } else if (base_avg[1] > kYPosLimit && lid_avg[1] < kYNegLimit) {
    result.first = true;
    result.second = fuchsia::ui::policy::PresentationMode::TENT;
  }

  if (result.first)
    FXL_VLOG(3) << "Presentation mode detected: "
                << fidl::ToUnderlying(result.second);

  return result;
}

internal::MovingAverage::MovingAverage(size_t size)
    : max_count_(size), count_(0), curr_(0), data_(size), sum_({0, 0, 0}) {
  FXL_CHECK(max_count_ <= std::numeric_limits<int16_t>::max())
      << "Integer truncation may occur. Reduce history size.";
}

AccelerometerData internal::MovingAverage::Average() {
  if (count_ == 0)
    return {0, 0, 0};

  AccelerometerData avg;
  // N.B. Truncation (and undefined behavior) guarded against by ctor's CHECK.
  int16_t denom_count = static_cast<int16_t>(count_);
  avg[0] = sum_[0] / denom_count;
  avg[1] = sum_[1] / denom_count;
  avg[2] = sum_[2] / denom_count;
  return avg;
}

void internal::MovingAverage::Update(AccelerometerData data) {
  if (count_ < max_count_) {
    ++count_;
  } else {
    sum_[0] -= data_[curr_][0];
    sum_[1] -= data_[curr_][1];
    sum_[2] -= data_[curr_][2];
  }
  sum_[0] += data[0];
  sum_[1] += data[1];
  sum_[2] += data[2];
  data_[curr_] = data;
  curr_ = (curr_ + 1) % max_count_;
}

}  // namespace presentation_mode
