// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/dom/window_timers.h"

#include <limits>
#include <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/dom/global_stats.h"
#include "nb/memory_scope.h"

namespace cobalt {
namespace dom {

int WindowTimers::SetTimeout(const TimerCallbackArg& handler, int timeout) {
  TRACK_MEMORY_SCOPE("DOM");
  int handle = GetFreeTimerHandle();
  DCHECK(handle);

  if (handle == 0) {  // unable to get a free timer handle
    // avoid accidentally overwriting existing timers
    return 0;
  }

  if (callbacks_active_) {
    auto* timer = new base::OneShotTimer();
    timer->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timeout),
                 base::Bind(&WindowTimers::RunTimerCallback,
                            base::Unretained(this), handle));
    timers_[handle] = new TimerInfo(
        owner_, std::unique_ptr<base::internal::TimerBase>(timer), handler);
    debugger_hooks_.AsyncTaskScheduled(
        timers_[handle], "SetTimeout",
        base::DebuggerHooks::AsyncTaskFrequency::kOneshot);
  } else {
    timers_[handle] = nullptr;
  }

  return handle;
}

void WindowTimers::ClearTimeout(int handle) { timers_.erase(handle); }

int WindowTimers::SetInterval(const TimerCallbackArg& handler, int timeout) {
  int handle = GetFreeTimerHandle();
  DCHECK(handle);

  if (handle == 0) {  // unable to get a free timer handle
    // avoid accidentally overwriting existing timers
    return 0;
  }

  if (callbacks_active_) {
    auto* timer(new base::RepeatingTimer());
    timer->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timeout),
                 base::Bind(&WindowTimers::RunTimerCallback,
                            base::Unretained(this), handle));
    timers_[handle] = new TimerInfo(
        owner_, std::unique_ptr<base::internal::TimerBase>(timer), handler);
    debugger_hooks_.AsyncTaskScheduled(
        timers_[handle], "SetInterval",
        base::DebuggerHooks::AsyncTaskFrequency::kRecurring);
  } else {
    timers_[handle] = nullptr;
  }

  return handle;
}

void WindowTimers::ClearInterval(int handle) {
  Timers::iterator timer = timers_.find(handle);
  if (timer != timers_.end()) {
    debugger_hooks_.AsyncTaskCanceled(timer->second);
    timers_.erase(timer);
  }
}

void WindowTimers::ClearAllIntervalsAndTimeouts() {
  for (auto& timer_entry : timers_) {
    debugger_hooks_.AsyncTaskCanceled(timer_entry.second);
  }
  timers_.clear();
}

void WindowTimers::DisableCallbacks() {
  callbacks_active_ = false;
  // Immediately cancel any pending timers.
  for (auto& timer_entry : timers_) {
    debugger_hooks_.AsyncTaskCanceled(timer_entry.second);
    timer_entry.second = nullptr;
  }
}

int WindowTimers::GetFreeTimerHandle() {
  int next_timer_index = current_timer_index_;
  while (true) {
    if (next_timer_index == std::numeric_limits<int>::max()) {
      next_timer_index = 1;
    } else {
      ++next_timer_index;
    }
    if (timers_.find(next_timer_index) == timers_.end()) {
      current_timer_index_ = next_timer_index;
      return current_timer_index_;
    }
    if (next_timer_index == current_timer_index_) {
      break;
    }
  }
  DLOG(INFO) << "No available timer handle.";
  return 0;
}

void WindowTimers::RunTimerCallback(int handle) {
  TRACE_EVENT0("cobalt::dom", "WindowTimers::RunTimerCallback");
  DCHECK(callbacks_active_)
      << "All timer callbacks should have already been cancelled.";
  Timers::iterator timer = timers_.find(handle);
  DCHECK(timer != timers_.end());

  // The callback is now being run. Track it in the global stats.
  GlobalStats::GetInstance()->StartJavaScriptEvent();

  {
    // Keep a |TimerInfo| reference, so it won't be released when running the
    // callback.
    scoped_refptr<TimerInfo> timer_info = timer->second;
    base::ScopedAsyncTask async_task(debugger_hooks_, timer_info);
    timer_info->callback_reference().value().Run();
  }

  // After running the callback, double check whether the timer is still there
  // since it might be deleted inside the callback.
  timer = timers_.find(handle);
  // If the timer is not deleted and is not running, it means it is an oneshot
  // timer and has just fired the shot, and it should be deleted now.
  if (timer != timers_.end() && !timer->second->timer()->IsRunning()) {
    debugger_hooks_.AsyncTaskCanceled(timer->second);
    timers_.erase(timer);
  }

  // The callback has finished running. Stop tracking it in the global stats.
  GlobalStats::GetInstance()->StopJavaScriptEvent();
}

}  // namespace dom
}  // namespace cobalt
