/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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 "timer.h"

#include <string>

#include <base/memory/scoped_ptr.h>

#include "metrics/metrics_library.h"

namespace chromeos_metrics {

base::TimeTicks ClockWrapper::GetCurrentTime() const {
  return base::TimeTicks::Now();
}

Timer::Timer()
    : timer_state_(kTimerStopped),
      clock_wrapper_(new ClockWrapper()) {}

bool Timer::Start() {
  elapsed_time_ = base::TimeDelta();  // Sets elapsed_time_ to zero.
  start_time_ = clock_wrapper_->GetCurrentTime();
  timer_state_ = kTimerRunning;
  return true;
}

bool Timer::Stop() {
  if (timer_state_ == kTimerStopped)
    return false;
  if (timer_state_ == kTimerRunning)
    elapsed_time_ += clock_wrapper_->GetCurrentTime() - start_time_;
  timer_state_ = kTimerStopped;
  return true;
}

bool Timer::Pause() {
  switch (timer_state_) {
    case kTimerStopped:
      if (!Start())
        return false;
      timer_state_ = kTimerPaused;
      return true;
    case kTimerRunning:
      timer_state_ = kTimerPaused;
      elapsed_time_ += clock_wrapper_->GetCurrentTime() - start_time_;
      return true;
    default:
      return false;
  }
}

bool Timer::Resume() {
  switch (timer_state_) {
    case kTimerStopped:
      return Start();
    case kTimerPaused:
      start_time_ = clock_wrapper_->GetCurrentTime();
      timer_state_ = kTimerRunning;
      return true;
    default:
      return false;
  }
}

bool Timer::Reset() {
  elapsed_time_ = base::TimeDelta();  // Sets elapsed_time_ to zero.
  timer_state_ = kTimerStopped;
  return true;
}

bool Timer::HasStarted() const {
  return timer_state_ != kTimerStopped;
}

bool Timer::GetElapsedTime(base::TimeDelta* elapsed_time) const {
  if (start_time_.is_null() || !elapsed_time)
    return false;
  *elapsed_time = elapsed_time_;
  if (timer_state_ == kTimerRunning) {
    *elapsed_time += clock_wrapper_->GetCurrentTime() - start_time_;
  }
  return true;
}

// static
MetricsLibraryInterface* TimerReporter::metrics_lib_ = nullptr;

TimerReporter::TimerReporter(const std::string& histogram_name, int min,
                             int max, int num_buckets)
    : histogram_name_(histogram_name),
      min_(min),
      max_(max),
      num_buckets_(num_buckets) {}

bool TimerReporter::ReportMilliseconds() const {
  base::TimeDelta elapsed_time;
  if (!metrics_lib_ || !GetElapsedTime(&elapsed_time)) return false;
  return metrics_lib_->SendToUMA(histogram_name_,
                                 elapsed_time.InMilliseconds(),
                                 min_,
                                 max_,
                                 num_buckets_);
}

}  // namespace chromeos_metrics
