// 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/ui/ws/user_activity_monitor.h"

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/time/default_tick_clock.h"

namespace ui {
namespace ws {

UserActivityMonitor::UserActivityMonitor(std::unique_ptr<base::TickClock> clock)
    : now_clock_(std::move(clock)) {
  if (!now_clock_)
    now_clock_ = base::WrapUnique(new base::DefaultTickClock);
  last_activity_ = now_clock_->NowTicks();
}

UserActivityMonitor::~UserActivityMonitor() {}

void UserActivityMonitor::OnUserActivity() {
  base::TimeTicks now = now_clock_->NowTicks();
  for (auto& pair : activity_observers_) {
    ActivityObserverInfo* info = &(pair.first);
    if (info->last_activity_notification.is_null() ||
        (now - info->last_activity_notification) > info->delay) {
      pair.second->OnUserActivity();
      info->last_activity_notification = now;
    }
  }

  // Wake up all the 'idle' observers.
  for (auto& pair : idle_observers_) {
    IdleObserverInfo* info = &(pair.first);
    if (info->idle_state == mojom::UserIdleObserver::IdleState::ACTIVE)
      continue;
    info->last_idle_state_notification = now;
    info->idle_state = mojom::UserIdleObserver::IdleState::ACTIVE;
    pair.second->OnUserIdleStateChanged(info->idle_state);
  }

  last_activity_ = now;

  // Start the timer if there are some idle observers.
  if (idle_timer_.IsRunning())
    idle_timer_.Reset();
}

void UserActivityMonitor::Add(mojom::UserActivityMonitorRequest request) {
  bindings_.AddBinding(this, std::move(request));
}

void UserActivityMonitor::AddUserActivityObserver(
    uint32_t delay_between_notify_secs,
    mojom::UserActivityObserverPtr observer) {
  ActivityObserverInfo info;
  info.delay = base::TimeDelta::FromSeconds(delay_between_notify_secs);
  observer.set_connection_error_handler(
      base::Bind(&UserActivityMonitor::OnActivityObserverDisconnected,
                 base::Unretained(this), observer.get()));
  activity_observers_.push_back(std::make_pair(info, std::move(observer)));
}

void UserActivityMonitor::AddUserIdleObserver(
    uint32_t idleness_in_minutes,
    mojom::UserIdleObserverPtr observer) {
  IdleObserverInfo info;
  info.idle_duration = base::TimeDelta::FromMinutes(idleness_in_minutes);
  base::TimeTicks now = now_clock_->NowTicks();
  DCHECK(!last_activity_.is_null());
  bool user_is_active = (now - last_activity_ < info.idle_duration);
  info.idle_state = user_is_active ? mojom::UserIdleObserver::IdleState::ACTIVE
                                   : mojom::UserIdleObserver::IdleState::IDLE;
  info.last_idle_state_notification = now;
  observer->OnUserIdleStateChanged(info.idle_state);
  observer.set_connection_error_handler(
      base::Bind(&UserActivityMonitor::OnIdleObserverDisconnected,
                 base::Unretained(this), observer.get()));
  idle_observers_.push_back(std::make_pair(info, std::move(observer)));
  if (user_is_active)
    ActivateIdleTimer();
}

void UserActivityMonitor::ActivateIdleTimer() {
  if (idle_timer_.IsRunning())
    return;
  idle_timer_.Start(FROM_HERE, base::TimeDelta::FromMinutes(1), this,
                    &UserActivityMonitor::OnMinuteTimer);
}

void UserActivityMonitor::OnMinuteTimer() {
  base::TimeTicks now = now_clock_->NowTicks();
  bool active_observer = false;
  for (auto& pair : idle_observers_) {
    IdleObserverInfo* info = &(pair.first);
    if (info->idle_state == mojom::UserIdleObserver::IdleState::IDLE)
      continue;
    if (now - info->last_idle_state_notification < info->idle_duration) {
      active_observer = true;
      continue;
    }
    info->last_idle_state_notification = now;
    info->idle_state = mojom::UserIdleObserver::IdleState::IDLE;
    pair.second->OnUserIdleStateChanged(info->idle_state);
  }
  // All observers are already notified of IDLE. No point running the timer
  // anymore.
  if (!active_observer)
    idle_timer_.Stop();
}

void UserActivityMonitor::OnActivityObserverDisconnected(
    mojom::UserActivityObserver* observer) {
  activity_observers_.erase(std::remove_if(
      activity_observers_.begin(), activity_observers_.end(),
      [observer](const std::pair<ActivityObserverInfo,
                                 mojom::UserActivityObserverPtr>& pair) {
        return pair.second.get() == observer;
      }));
}

void UserActivityMonitor::OnIdleObserverDisconnected(
    mojom::UserIdleObserver* observer) {
  idle_observers_.erase(std::remove_if(
      idle_observers_.begin(), idle_observers_.end(),
      [observer](
          const std::pair<IdleObserverInfo, mojom::UserIdleObserverPtr>& pair) {
        return pair.second.get() == observer;
      }));
}

}  // namespace ws
}  // namespace ui
