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

#include "base/timer.h"

#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/platform_thread.h"

namespace base {

// BaseTimerTaskInternal is a simple delegate for scheduling a callback to
// Timer in the thread's default task runner. It also handles the following
// edge cases:
// - deleted by the task runner.
// - abandoned (orphaned) by Timer.
class BaseTimerTaskInternal {
 public:
  BaseTimerTaskInternal(Timer* timer)
      : timer_(timer) {
  }

  ~BaseTimerTaskInternal() {
    // This task may be getting cleared because the task runner has been
    // destructed.  If so, don't leave Timer with a dangling pointer
    // to this.
    if (timer_)
      timer_->StopAndAbandon();
  }

  void Run() {
    // timer_ is NULL if we were abandoned.
    if (!timer_)
      return;

    // *this will be deleted by the task runner, so Timer needs to
    // forget us:
    timer_->scheduled_task_ = NULL;

    // Although Timer should not call back into *this, let's clear
    // the timer_ member first to be pedantic.
    Timer* timer = timer_;
    timer_ = NULL;
    timer->RunScheduledTask();
  }

  // The task remains in the MessageLoop queue, but nothing will happen when it
  // runs.
  void Abandon() {
    timer_ = NULL;
  }

 private:
  Timer* timer_;
};

Timer::Timer(bool retain_user_task, bool is_repeating)
    : scheduled_task_(NULL),
      thread_id_(0),
      is_repeating_(is_repeating),
      retain_user_task_(retain_user_task),
      is_running_(false) {
}

Timer::Timer(const tracked_objects::Location& posted_from,
             TimeDelta delay,
             const base::Closure& user_task,
             bool is_repeating)
    : scheduled_task_(NULL),
      posted_from_(posted_from),
      delay_(delay),
      user_task_(user_task),
      thread_id_(0),
      is_repeating_(is_repeating),
      retain_user_task_(true),
      is_running_(false) {
}

Timer::~Timer() {
  StopAndAbandon();
}

void Timer::Start(const tracked_objects::Location& posted_from,
                  TimeDelta delay,
                  const base::Closure& user_task) {
  SetTaskInfo(posted_from, delay, user_task);
  Reset();
}

void Timer::Stop() {
  is_running_ = false;
  if (!retain_user_task_)
    user_task_.Reset();
}

void Timer::Reset() {
  DCHECK(!user_task_.is_null());

  // If there's no pending task, start one up and return.
  if (!scheduled_task_) {
    PostNewScheduledTask(delay_);
    return;
  }

  // Set the new desired_run_time_.
  desired_run_time_ = TimeTicks::Now() + delay_;

  // We can use the existing scheduled task if it arrives before the new
  // desired_run_time_.
  if (desired_run_time_ > scheduled_run_time_) {
    is_running_ = true;
    return;
  }

  // We can't reuse the scheduled_task_, so abandon it and post a new one.
  AbandonScheduledTask();
  PostNewScheduledTask(delay_);
}

void Timer::SetTaskInfo(const tracked_objects::Location& posted_from,
                        TimeDelta delay,
                        const base::Closure& user_task) {
  posted_from_ = posted_from;
  delay_ = delay;
  user_task_ = user_task;
}

void Timer::PostNewScheduledTask(TimeDelta delay) {
  DCHECK(scheduled_task_ == NULL);
  is_running_ = true;
  scheduled_task_ = new BaseTimerTaskInternal(this);
  ThreadTaskRunnerHandle::Get()->PostDelayedTask(posted_from_,
      base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_)),
      delay);
  scheduled_run_time_ = desired_run_time_ = TimeTicks::Now() + delay;
  // Remember the thread ID that posts the first task -- this will be verified
  // later when the task is abandoned to detect misuse from multiple threads.
  if (!thread_id_)
    thread_id_ = static_cast<int>(PlatformThread::CurrentId());
}

void Timer::AbandonScheduledTask() {
  DCHECK(thread_id_ == 0 ||
         thread_id_ == static_cast<int>(PlatformThread::CurrentId()));
  if (scheduled_task_) {
    scheduled_task_->Abandon();
    scheduled_task_ = NULL;
  }
}

void Timer::RunScheduledTask() {
  // Task may have been disabled.
  if (!is_running_)
    return;

  // First check if we need to delay the task because of a new target time.
  if (desired_run_time_ > scheduled_run_time_) {
    // TimeTicks::Now() can be expensive, so only call it if we know the user
    // has changed the desired_run_time_.
    TimeTicks now = TimeTicks::Now();
    // Task runner may have called us late anyway, so only post a continuation
    // task if the desired_run_time_ is in the future.
    if (desired_run_time_ > now) {
      // Post a new task to span the remaining time.
      PostNewScheduledTask(desired_run_time_ - now);
      return;
    }
  }

  // Make a local copy of the task to run. The Stop method will reset the
  // user_task_ member if retain_user_task_ is false.
  base::Closure task = user_task_;

  if (is_repeating_)
    PostNewScheduledTask(delay_);
  else
    Stop();

  task.Run();

  // No more member accesses here: *this could be deleted at this point.
}

}  // namespace base
