/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

#ifndef GRPC_CORE_LIB_IOMGR_TIMER_H
#define GRPC_CORE_LIB_IOMGR_TIMER_H

#include <grpc/support/port_platform.h>

#include "src/core/lib/iomgr/port.h"

#include <grpc/support/time.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"

typedef struct grpc_timer {
  grpc_millis deadline;
  uint32_t heap_index; /* INVALID_HEAP_INDEX if not in heap */
  bool pending;
  struct grpc_timer* next;
  struct grpc_timer* prev;
  grpc_closure* closure;
#ifndef NDEBUG
  struct grpc_timer* hash_table_next;
#endif

  // Optional field used by custom timers
  void* custom_timer;
} grpc_timer;

typedef enum {
  GRPC_TIMERS_NOT_CHECKED,
  GRPC_TIMERS_CHECKED_AND_EMPTY,
  GRPC_TIMERS_FIRED,
} grpc_timer_check_result;

typedef struct grpc_timer_vtable {
  void (*init)(grpc_timer* timer, grpc_millis, grpc_closure* closure);
  void (*cancel)(grpc_timer* timer);

  /* Internal API */
  grpc_timer_check_result (*check)(grpc_millis* next);
  void (*list_init)();
  void (*list_shutdown)(void);
  void (*consume_kick)(void);
} grpc_timer_vtable;

/* Initialize *timer. When expired or canceled, closure will be called with
   error set to indicate if it expired (GRPC_ERROR_NONE) or was canceled
   (GRPC_ERROR_CANCELLED). *closure is guaranteed to be called exactly once, and
   application code should check the error to determine how it was invoked. The
   application callback is also responsible for maintaining information about
   when to free up any user-level state. Behavior is undefined for a deadline of
   GRPC_MILLIS_INF_FUTURE. */
void grpc_timer_init(grpc_timer* timer, grpc_millis deadline,
                     grpc_closure* closure);

/* Initialize *timer without setting it. This can later be passed through
   the regular init or cancel */
void grpc_timer_init_unset(grpc_timer* timer);

/* Note that there is no timer destroy function. This is because the
   timer is a one-time occurrence with a guarantee that the callback will
   be called exactly once, either at expiration or cancellation. Thus, all
   the internal timer event management state is destroyed just before
   that callback is invoked. If the user has additional state associated with
   the timer, the user is responsible for determining when it is safe to
   destroy that state. */

/* Cancel an *timer.
   There are three cases:
   1. We normally cancel the timer
   2. The timer has already run
   3. We can't cancel the timer because it is "in flight".

   In all of these cases, the cancellation is still considered successful.
   They are essentially distinguished in that the timer_cb will be run
   exactly once from either the cancellation (with error GRPC_ERROR_CANCELLED)
   or from the activation (with error GRPC_ERROR_NONE).

   Note carefully that the callback function MAY occur in the same callstack
   as grpc_timer_cancel. It's expected that most timers will be cancelled (their
   primary use is to implement deadlines), and so this code is optimized such
   that cancellation costs as little as possible. Making callbacks run inline
   matches this aim.

   Requires: cancel() must happen after init() on a given timer */
void grpc_timer_cancel(grpc_timer* timer);

/* iomgr internal api for dealing with timers */

/* Check for timers to be run, and run them.
   Return true if timer callbacks were executed.
   If next is non-null, TRY to update *next with the next running timer
   IF that timer occurs before *next current value.
   *next is never guaranteed to be updated on any given execution; however,
   with high probability at least one thread in the system will see an update
   at any time slice. */
grpc_timer_check_result grpc_timer_check(grpc_millis* next);
void grpc_timer_list_init();
void grpc_timer_list_shutdown();

/* Consume a kick issued by grpc_kick_poller */
void grpc_timer_consume_kick(void);

/* the following must be implemented by each iomgr implementation */
void grpc_kick_poller(void);

/* Sets the timer implementation */
void grpc_set_timer_impl(grpc_timer_vtable* vtable);

#endif /* GRPC_CORE_LIB_IOMGR_TIMER_H */
