/**
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.
 */

/**
 * @file AsyncTimer.cc
 */
#include "tscpp/api/AsyncTimer.h"
#include "ts/ts.h"
#include "logging_internal.h"

using namespace atscppapi;

struct atscppapi::AsyncTimerState {
  TSCont cont_ = nullptr;
  AsyncTimer::Type type_;
  int period_in_ms_;
  int initial_period_in_ms_;
  TSThreadPool thread_pool_;
  TSAction initial_timer_action_  = nullptr;
  TSAction periodic_timer_action_ = nullptr;
  AsyncTimer *timer_              = nullptr;
  std::shared_ptr<AsyncDispatchControllerBase> dispatch_controller_{};
  AsyncTimerState(AsyncTimer::Type type, int period_in_ms, int initial_period_in_ms, TSThreadPool thread_pool, AsyncTimer *timer)
    : type_(type),
      period_in_ms_(period_in_ms),
      initial_period_in_ms_(initial_period_in_ms),
      thread_pool_(thread_pool),
      timer_(timer)
  {
  }
};

namespace
{
int
handleTimerEvent(TSCont cont, TSEvent event, void *edata)
{
  AsyncTimerState *state = static_cast<AsyncTimerState *>(TSContDataGet(cont));
  if (state->initial_timer_action_) {
    LOG_DEBUG("Received initial timer event.");
    state->initial_timer_action_ = nullptr; // mark it so that it won't be canceled later on
    if (state->type_ == AsyncTimer::TYPE_PERIODIC) {
      LOG_DEBUG("Scheduling periodic event now");
      state->periodic_timer_action_ = TSContScheduleEveryOnPool(state->cont_, state->period_in_ms_, state->thread_pool_);
    }
  }
  if (!state->dispatch_controller_->dispatch()) {
    LOG_DEBUG("Receiver has died. Destroying timer");
    delete state->timer_; // auto-destruct only in this case
  }
  return 0;
}
} // namespace

AsyncTimer::AsyncTimer(Type type, int period_in_ms, int initial_period_in_ms, TSThreadPool thread_pool)
{
  state_        = new AsyncTimerState(type, period_in_ms, initial_period_in_ms, thread_pool, this);
  state_->cont_ = TSContCreate(handleTimerEvent, TSMutexCreate());
  TSContDataSet(state_->cont_, static_cast<void *>(state_));
}

void
AsyncTimer::run()
{
  state_->dispatch_controller_ = getDispatchController(); // keep a copy in state so that cont handler can use it
  int one_off_timeout_in_ms    = 0;
  int regular_timeout_in_ms    = 0;
  if (state_->type_ == AsyncTimer::TYPE_ONE_OFF) {
    one_off_timeout_in_ms = state_->period_in_ms_;
  } else {
    one_off_timeout_in_ms = state_->initial_period_in_ms_;
    regular_timeout_in_ms = state_->period_in_ms_;
  }
  if (one_off_timeout_in_ms) {
    LOG_DEBUG("Scheduling initial/one-off event");
    state_->initial_timer_action_ = TSContScheduleOnPool(state_->cont_, one_off_timeout_in_ms, state_->thread_pool_);
  } else if (regular_timeout_in_ms) {
    LOG_DEBUG("Scheduling regular timer events");
    state_->periodic_timer_action_ = TSContScheduleEveryOnPool(state_->cont_, regular_timeout_in_ms, state_->thread_pool_);
  }
}

void
AsyncTimer::cancel()
{
  // Assume this object is locked and the state isn't being updated elsewhere.
  // Note that is not the same as the contained continuation being locked.
  TSCont contp{state_->cont_}; // save this
  if (!contp) {
    LOG_DEBUG("Already canceled");
    return;
  }

  auto mutex{TSContMutexGet(contp)};
  TSMutexLock(mutex); // prevent event dispatch for the continuation during this cancel.

  if (state_->initial_timer_action_) {
    LOG_DEBUG("Canceling initial timer action");
    TSActionCancel(state_->initial_timer_action_);
  }
  if (state_->periodic_timer_action_) {
    LOG_DEBUG("Canceling periodic timer action");
    TSActionCancel(state_->periodic_timer_action_);
  }
  state_->cont_ = nullptr;

  TSMutexUnlock(mutex);

  LOG_DEBUG("Destroying cont");
  TSContDestroy(contp);
}

AsyncTimer::~AsyncTimer()
{
  cancel();
  delete state_;
}
