// 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 "src/cobalt/bin/app/timer_manager.h"

#include <lib/async/cpp/time.h>

#include <iostream>
#include <ostream>
#include <thread>

namespace cobalt {

using fuchsia::cobalt::Status;
using std::string;

const uint32_t kMaxTimerTimeout = 300;

void TimerVal::AddStart(uint32_t metric_id, uint32_t event_code, const std::string& component,
                        uint32_t encoding_id, int64_t timestamp) {
  this->metric_id = metric_id;
  this->encoding_id = encoding_id;
  this->event_code = event_code;
  this->component = component;
  this->start_timestamp = timestamp;
}

void TimerVal::AddEnd(int64_t timestamp, const std::string& part_name) {
  this->end_timestamp = timestamp;
  this->part_name = std::move(part_name);
}

TimerManager::TimerManager(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}

TimerManager::~TimerManager() {}

bool TimerManager::isReady(const std::unique_ptr<TimerVal>& timer_val_ptr) {
  if (!timer_val_ptr) {
    return false;
  }
  FX_DCHECK(timer_val_ptr->start_timestamp > 0 && timer_val_ptr->end_timestamp > 0)
      << "Incomplete timer was returned.";
  return true;
}

bool TimerManager::isValidTimerArguments(fidl::StringPtr timer_id, int64_t timestamp,
                                         uint32_t timeout_s) {
  if (!timer_id.has_value() || timer_id.value().empty()) {
    FX_DLOGS(ERROR) << "Invalid timer_id.";
    return false;
  }
  if (timestamp <= 0) {
    FX_DLOGS(ERROR) << "Invalid timestamp.";
    return false;
  }
  if (timeout_s <= 0 || timeout_s > kMaxTimerTimeout) {
    FX_DLOGS(ERROR) << "Invalid timeout_s.";
    return false;
  }
  return true;
}

Status TimerManager::GetTimerValWithStart(uint32_t metric_id, uint32_t event_code,
                                          const std::string& component, uint32_t encoding_id,
                                          const std::string& timer_id, int64_t timestamp,
                                          uint32_t timeout_s,
                                          std::unique_ptr<TimerVal>* timer_val_ptr) {
  if (!timer_val_ptr || !isValidTimerArguments(timer_id, timestamp, timeout_s)) {
    return Status::INVALID_ARGUMENTS;
  }

  timer_val_ptr->reset();
  auto timer_val_iter = timer_values_.find(timer_id);

  // An expired timer with that timer_id exists.
  if (timer_val_iter != timer_values_.end() &&
      timer_val_iter->second->expiry_time < async::Now(dispatcher_)) {
    timer_values_.erase(timer_val_iter);
    timer_val_iter = timer_values_.end();
  }

  // No timer with the timer_id
  if (timer_val_iter == timer_values_.end()) {
    auto& timer = timer_values_[timer_id];
    timer.reset(new TimerVal());
    timer->AddStart(metric_id, event_code, component, encoding_id, timestamp);
    ScheduleExpiryTask(timer_id, timeout_s, &timer);
    return Status::OK;
  }

  // A valid start to a timer already exists with that timer_id.
  if (timer_val_iter->second->start_timestamp > 0) {
    timer_values_.erase(timer_id);
    return Status::INVALID_ARGUMENTS;
  }

  // Return TimerVal with start_timestamp and end_timestamp.
  timer_val_iter->second->AddStart(metric_id, event_code, component, encoding_id, timestamp);
  MoveTimerToTimerVal(&timer_val_iter, timer_val_ptr);
  return Status::OK;
}

Status TimerManager::GetTimerValWithEnd(const std::string& timer_id, int64_t timestamp,
                                        uint32_t timeout_s,
                                        std::unique_ptr<TimerVal>* timer_val_ptr) {
  if (!timer_val_ptr || !isValidTimerArguments(timer_id, timestamp, timeout_s)) {
    return Status::INVALID_ARGUMENTS;
  }

  timer_val_ptr->reset();
  auto timer_val_iter = timer_values_.find(timer_id);

  // An expired timer with that timer_id exists.
  if (timer_val_iter != timer_values_.end() &&
      timer_val_iter->second->expiry_time < async::Now(dispatcher_)) {
    timer_values_.erase(timer_val_iter);
    timer_val_iter = timer_values_.end();
  }

  // No timer with the timer_id.
  if (timer_val_iter == timer_values_.end()) {
    auto& timer = timer_values_[timer_id];
    timer.reset(new TimerVal());
    timer->end_timestamp = timestamp;
    ScheduleExpiryTask(timer_id, timeout_s, &timer);
    return Status::OK;
  }

  // A valid end to a timer already exists with that timer_id.
  if (timer_val_iter->second->end_timestamp > 0) {
    timer_values_.erase(timer_val_iter);
    return Status::INVALID_ARGUMENTS;
  }

  // Return TimerVal with start_timestamp and end_timestamp.
  timer_val_iter->second->end_timestamp = timestamp;
  MoveTimerToTimerVal(&timer_val_iter, timer_val_ptr);
  return Status::OK;
}

Status TimerManager::GetTimerValWithEnd(const std::string& timer_id, int64_t timestamp,
                                        uint32_t timeout_s, const std::string& part_name,
                                        std::unique_ptr<TimerVal>* timer_val_ptr) {
  if (!timer_val_ptr || !isValidTimerArguments(timer_id, timestamp, timeout_s)) {
    return Status::INVALID_ARGUMENTS;
  }

  timer_val_ptr->reset();
  auto timer_val_iter = timer_values_.find(timer_id);

  // An expired timer with that timer_id exists.
  if (timer_val_iter != timer_values_.end() &&
      timer_val_iter->second->expiry_time < async::Now(dispatcher_)) {
    timer_values_.erase(timer_val_iter);
    timer_val_iter = timer_values_.end();
  }

  // No timer with the timer_id.
  if (timer_val_iter == timer_values_.end()) {
    auto& timer = timer_values_[timer_id];
    timer.reset(new TimerVal());
    ScheduleExpiryTask(timer_id, timeout_s, &timer);
    return Status::OK;
  }

  // A valid end to a timer already exists with that timer_id.
  if (timer_val_iter->second->end_timestamp > 0) {
    timer_values_.erase(timer_val_iter);
    return Status::INVALID_ARGUMENTS;
  }

  // Return TimerVal with start_timestamp and end_timestamp.
  MoveTimerToTimerVal(&timer_val_iter, timer_val_ptr);
  return Status::OK;
}

void TimerManager::MoveTimerToTimerVal(
    std::unordered_map<std::string, std::unique_ptr<TimerVal>>::iterator* timer_val_iter,
    std::unique_ptr<TimerVal>* timer_val_ptr) {
  zx_status_t status = (*timer_val_iter)->second->expiry_task.Cancel();
  if (status != ZX_OK & status != ZX_ERR_BAD_STATE) {
    FX_DLOGS(ERROR) << "Failed to cancel task: status = " << status;
  }

  *timer_val_ptr = std::move((*timer_val_iter)->second);
  timer_values_.erase(*timer_val_iter);
}

void TimerManager::ScheduleExpiryTask(const std::string& timer_id, uint32_t timeout_s,
                                      std::unique_ptr<TimerVal>* timer_val_ptr) {
  (*timer_val_ptr)->expiry_time = async::Now(dispatcher_) + zx::sec(timeout_s);

  (*timer_val_ptr)
      ->expiry_task.set_handler([this, timer_id, me = &((*timer_val_ptr)->expiry_task)] {
        auto timer_val_iter = timer_values_.find(timer_id);
        FX_DCHECK(&(timer_val_iter->second->expiry_task) == me);
        timer_values_.erase(timer_val_iter);
      });

  zx_status_t status = (*timer_val_ptr)->expiry_task.PostDelayed(dispatcher_, zx::sec(timeout_s));
  if (status != ZX_OK & status != ZX_ERR_BAD_STATE) {
    FX_DLOGS(ERROR) << "Failed to post task: status = " << status;
  }
}
}  // namespace cobalt
