/*
 *
 * Copyright 2017 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.
 *
 */

#include <grpc/support/port_platform.h>

#include "src/core/ext/filters/max_age/max_age_filter.h"

#include <limits.h>
#include <string.h>

#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/http2_errors.h"

#define DEFAULT_MAX_CONNECTION_AGE_MS INT_MAX
#define DEFAULT_MAX_CONNECTION_AGE_GRACE_MS INT_MAX
#define DEFAULT_MAX_CONNECTION_IDLE_MS INT_MAX
#define MAX_CONNECTION_AGE_JITTER 0.1

#define MAX_CONNECTION_AGE_INTEGER_OPTIONS \
  { DEFAULT_MAX_CONNECTION_AGE_MS, 1, INT_MAX }
#define MAX_CONNECTION_IDLE_INTEGER_OPTIONS \
  { DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX }

/* States for idle_state in channel_data */
#define MAX_IDLE_STATE_INIT ((gpr_atm)0)
#define MAX_IDLE_STATE_SEEN_EXIT_IDLE ((gpr_atm)1)
#define MAX_IDLE_STATE_SEEN_ENTER_IDLE ((gpr_atm)2)
#define MAX_IDLE_STATE_TIMER_SET ((gpr_atm)3)

namespace {
struct channel_data {
  /* We take a reference to the channel stack for the timer callback */
  grpc_channel_stack* channel_stack;
  /* Guards access to max_age_timer, max_age_timer_pending, max_age_grace_timer
     and max_age_grace_timer_pending */
  gpr_mu max_age_timer_mu;
  /* True if the max_age timer callback is currently pending */
  bool max_age_timer_pending;
  /* True if the max_age_grace timer callback is currently pending */
  bool max_age_grace_timer_pending;
  /* The timer for checking if the channel has reached its max age */
  grpc_timer max_age_timer;
  /* The timer for checking if the max-aged channel has uesed up the grace
     period */
  grpc_timer max_age_grace_timer;
  /* The timer for checking if the channel's idle duration reaches
     max_connection_idle */
  grpc_timer max_idle_timer;
  /* Allowed max time a channel may have no outstanding rpcs */
  grpc_millis max_connection_idle;
  /* Allowed max time a channel may exist */
  grpc_millis max_connection_age;
  /* Allowed grace period after the channel reaches its max age */
  grpc_millis max_connection_age_grace;
  /* Closure to run when the channel's idle duration reaches max_connection_idle
     and should be closed gracefully */
  grpc_closure max_idle_timer_cb;
  /* Closure to run when the channel reaches its max age and should be closed
     gracefully */
  grpc_closure close_max_age_channel;
  /* Closure to run the channel uses up its max age grace time and should be
     closed forcibly */
  grpc_closure force_close_max_age_channel;
  /* Closure to run when the init fo channel stack is done and the max_idle
     timer should be started */
  grpc_closure start_max_idle_timer_after_init;
  /* Closure to run when the init fo channel stack is done and the max_age timer
     should be started */
  grpc_closure start_max_age_timer_after_init;
  /* Closure to run when the goaway op is finished and the max_age_timer */
  grpc_closure start_max_age_grace_timer_after_goaway_op;
  /* Closure to run when the channel connectivity state changes */
  grpc_closure channel_connectivity_changed;
  /* Records the current connectivity state */
  grpc_connectivity_state connectivity_state;
  /* Number of active calls */
  gpr_atm call_count;
  /* TODO(zyc): C++lize this state machine */
  /* 'idle_state' holds the states of max_idle_timer and channel idleness.
      It can contain one of the following values:
     +--------------------------------+----------------+---------+
     |           idle_state           | max_idle_timer | channel |
     +--------------------------------+----------------+---------+
     | MAX_IDLE_STATE_INIT            | unset          | busy    |
     | MAX_IDLE_STATE_TIMER_SET       | set, valid     | idle    |
     | MAX_IDLE_STATE_SEEN_EXIT_IDLE  | set, invalid   | busy    |
     | MAX_IDLE_STATE_SEEN_ENTER_IDLE | set, invalid   | idle    |
     +--------------------------------+----------------+---------+

     MAX_IDLE_STATE_INIT: The initial and final state of 'idle_state'. The
     channel has 1 or 1+ active calls, and the the timer is not set. Note that
     we may put a virtual call to hold this state at channel initialization or
     shutdown, so that the channel won't enter other states.

     MAX_IDLE_STATE_TIMER_SET: The state after the timer is set and no calls
     have arrived after the timer is set. The channel must have 0 active call in
     this state. If the timer is fired in this state, we will close the channel
     due to idleness.

     MAX_IDLE_STATE_SEEN_EXIT_IDLE: The state after the timer is set and at
     least one call has arrived after the timer is set. The channel must have 1
     or 1+ active calls in this state. If the timer is fired in this state, we
     won't reschudle it.

     MAX_IDLE_STATE_SEEN_ENTER_IDLE: The state after the timer is set and the at
     least one call has arrived after the timer is set, BUT the channel
     currently has 1 or 1+ active calls. If the timer is fired in this state, we
     will reschudle it.

     max_idle_timer will not be cancelled (unless the channel is shutting down).
     If the timer callback is called when the max_idle_timer is valid (i.e.
     idle_state is MAX_IDLE_STATE_TIMER_SET), the channel will be closed due to
     idleness, otherwise the channel won't be changed.

     State transitions:
         MAX_IDLE_STATE_INIT <-------3------ MAX_IDLE_STATE_SEEN_EXIT_IDLE
              ^    |                              ^     ^    |
              |    |                              |     |    |
              1    2     +-----------4------------+     6    7
              |    |     |                              |    |
              |    v     |                              |    v
       MAX_IDLE_STATE_TIMER_SET <----5------ MAX_IDLE_STATE_SEEN_ENTER_IDLE

     For 1, 3, 5 :  See max_idle_timer_cb() function
     For 2, 7    :  See decrease_call_count() function
     For 4, 6    :  See increase_call_count() function */
  gpr_atm idle_state;
  /* Time when the channel finished its last outstanding call, in grpc_millis */
  gpr_atm last_enter_idle_time_millis;
};
}  // namespace

/* Increase the nubmer of active calls. Before the increasement, if there are no
   calls, the max_idle_timer should be cancelled. */
static void increase_call_count(channel_data* chand) {
  /* Exit idle */
  if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) {
    while (true) {
      gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state);
      switch (idle_state) {
        case MAX_IDLE_STATE_TIMER_SET:
          /* max_idle_timer_cb may have already set idle_state to
             MAX_IDLE_STATE_INIT, in this case, we don't need to set it to
             MAX_IDLE_STATE_SEEN_EXIT_IDLE */
          gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET,
                          MAX_IDLE_STATE_SEEN_EXIT_IDLE);
          return;
        case MAX_IDLE_STATE_SEEN_ENTER_IDLE:
          gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE);
          return;
        default:
          /* try again */
          break;
      }
    }
  }
}

/* Decrease the nubmer of active calls. After the decrement, if there are no
   calls, the max_idle_timer should be started. */
static void decrease_call_count(channel_data* chand) {
  /* Enter idle */
  if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) {
    gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis,
                             (gpr_atm)grpc_core::ExecCtx::Get()->Now());
    while (true) {
      gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state);
      switch (idle_state) {
        case MAX_IDLE_STATE_INIT:
          GRPC_CHANNEL_STACK_REF(chand->channel_stack,
                                 "max_age max_idle_timer");
          grpc_timer_init(
              &chand->max_idle_timer,
              grpc_core::ExecCtx::Get()->Now() + chand->max_connection_idle,
              &chand->max_idle_timer_cb);
          gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET);
          return;
        case MAX_IDLE_STATE_SEEN_EXIT_IDLE:
          if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE,
                              MAX_IDLE_STATE_SEEN_ENTER_IDLE)) {
            return;
          }
          break;
        default:
          /* try again */
          break;
      }
    }
  }
}

static void start_max_idle_timer_after_init(void* arg, grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  /* Decrease call_count. If there are no active calls at this time,
     max_idle_timer will start here. If the number of active calls is not 0,
     max_idle_timer will start after all the active calls end. */
  decrease_call_count(chand);
  GRPC_CHANNEL_STACK_UNREF(chand->channel_stack,
                           "max_age start_max_idle_timer_after_init");
}

static void start_max_age_timer_after_init(void* arg, grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  gpr_mu_lock(&chand->max_age_timer_mu);
  chand->max_age_timer_pending = true;
  GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_age_timer");
  grpc_timer_init(&chand->max_age_timer,
                  grpc_core::ExecCtx::Get()->Now() + chand->max_connection_age,
                  &chand->close_max_age_channel);
  gpr_mu_unlock(&chand->max_age_timer_mu);
  grpc_transport_op* op = grpc_make_transport_op(nullptr);
  op->on_connectivity_state_change = &chand->channel_connectivity_changed;
  op->connectivity_state = &chand->connectivity_state;
  grpc_channel_next_op(grpc_channel_stack_element(chand->channel_stack, 0), op);
  GRPC_CHANNEL_STACK_UNREF(chand->channel_stack,
                           "max_age start_max_age_timer_after_init");
}

static void start_max_age_grace_timer_after_goaway_op(void* arg,
                                                      grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  gpr_mu_lock(&chand->max_age_timer_mu);
  chand->max_age_grace_timer_pending = true;
  GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_age_grace_timer");
  grpc_timer_init(
      &chand->max_age_grace_timer,
      chand->max_connection_age_grace == GRPC_MILLIS_INF_FUTURE
          ? GRPC_MILLIS_INF_FUTURE
          : grpc_core::ExecCtx::Get()->Now() + chand->max_connection_age_grace,
      &chand->force_close_max_age_channel);
  gpr_mu_unlock(&chand->max_age_timer_mu);
  GRPC_CHANNEL_STACK_UNREF(chand->channel_stack,
                           "max_age start_max_age_grace_timer_after_goaway_op");
}

static void close_max_idle_channel(channel_data* chand) {
  /* Prevent the max idle timer from being set again */
  gpr_atm_no_barrier_fetch_add(&chand->call_count, 1);
  grpc_transport_op* op = grpc_make_transport_op(nullptr);
  op->goaway_error =
      grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_idle"),
                         GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR);
  grpc_channel_element* elem =
      grpc_channel_stack_element(chand->channel_stack, 0);
  elem->filter->start_transport_op(elem, op);
}

static void max_idle_timer_cb(void* arg, grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  if (error == GRPC_ERROR_NONE) {
    bool try_again = true;
    while (try_again) {
      gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state);
      switch (idle_state) {
        case MAX_IDLE_STATE_TIMER_SET:
          close_max_idle_channel(chand);
          /* This MAX_IDLE_STATE_INIT is a final state, we don't have to check
           * if idle_state has been changed */
          gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_INIT);
          try_again = false;
          break;
        case MAX_IDLE_STATE_SEEN_EXIT_IDLE:
          if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE,
                              MAX_IDLE_STATE_INIT)) {
            try_again = false;
          }
          break;
        case MAX_IDLE_STATE_SEEN_ENTER_IDLE:
          GRPC_CHANNEL_STACK_REF(chand->channel_stack,
                                 "max_age max_idle_timer");
          grpc_timer_init(&chand->max_idle_timer,
                          static_cast<grpc_millis>(gpr_atm_no_barrier_load(
                              &chand->last_enter_idle_time_millis)) +
                              chand->max_connection_idle,
                          &chand->max_idle_timer_cb);
          /* idle_state may have already been set to
             MAX_IDLE_STATE_SEEN_EXIT_IDLE by increase_call_count(), in this
             case, we don't need to set it to MAX_IDLE_STATE_TIMER_SET */
          gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_ENTER_IDLE,
                          MAX_IDLE_STATE_TIMER_SET);
          try_again = false;
          break;
        default:
          /* try again */
          break;
      }
    }
  }
  GRPC_CHANNEL_STACK_UNREF(chand->channel_stack, "max_age max_idle_timer");
}

static void close_max_age_channel(void* arg, grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  gpr_mu_lock(&chand->max_age_timer_mu);
  chand->max_age_timer_pending = false;
  gpr_mu_unlock(&chand->max_age_timer_mu);
  if (error == GRPC_ERROR_NONE) {
    GRPC_CHANNEL_STACK_REF(chand->channel_stack,
                           "max_age start_max_age_grace_timer_after_goaway_op");
    grpc_transport_op* op = grpc_make_transport_op(
        &chand->start_max_age_grace_timer_after_goaway_op);
    op->goaway_error =
        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_age"),
                           GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR);
    grpc_channel_element* elem =
        grpc_channel_stack_element(chand->channel_stack, 0);
    elem->filter->start_transport_op(elem, op);
  } else if (error != GRPC_ERROR_CANCELLED) {
    GRPC_LOG_IF_ERROR("close_max_age_channel", error);
  }
  GRPC_CHANNEL_STACK_UNREF(chand->channel_stack, "max_age max_age_timer");
}

static void force_close_max_age_channel(void* arg, grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  gpr_mu_lock(&chand->max_age_timer_mu);
  chand->max_age_grace_timer_pending = false;
  gpr_mu_unlock(&chand->max_age_timer_mu);
  if (error == GRPC_ERROR_NONE) {
    grpc_transport_op* op = grpc_make_transport_op(nullptr);
    op->disconnect_with_error =
        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel reaches max age");
    grpc_channel_element* elem =
        grpc_channel_stack_element(chand->channel_stack, 0);
    elem->filter->start_transport_op(elem, op);
  } else if (error != GRPC_ERROR_CANCELLED) {
    GRPC_LOG_IF_ERROR("force_close_max_age_channel", error);
  }
  GRPC_CHANNEL_STACK_UNREF(chand->channel_stack, "max_age max_age_grace_timer");
}

static void channel_connectivity_changed(void* arg, grpc_error* error) {
  channel_data* chand = static_cast<channel_data*>(arg);
  if (chand->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
    grpc_transport_op* op = grpc_make_transport_op(nullptr);
    op->on_connectivity_state_change = &chand->channel_connectivity_changed;
    op->connectivity_state = &chand->connectivity_state;
    grpc_channel_next_op(grpc_channel_stack_element(chand->channel_stack, 0),
                         op);
  } else {
    gpr_mu_lock(&chand->max_age_timer_mu);
    if (chand->max_age_timer_pending) {
      grpc_timer_cancel(&chand->max_age_timer);
      chand->max_age_timer_pending = false;
    }
    if (chand->max_age_grace_timer_pending) {
      grpc_timer_cancel(&chand->max_age_grace_timer);
      chand->max_age_grace_timer_pending = false;
    }
    gpr_mu_unlock(&chand->max_age_timer_mu);
    /* If there are no active calls, this increasement will cancel
       max_idle_timer, and prevent max_idle_timer from being started in the
       future. */
    increase_call_count(chand);
    if (gpr_atm_acq_load(&chand->idle_state) == MAX_IDLE_STATE_SEEN_EXIT_IDLE) {
      grpc_timer_cancel(&chand->max_idle_timer);
    }
  }
}

/* A random jitter of +/-10% will be added to MAX_CONNECTION_AGE to spread out
   connection storms. Note that the MAX_CONNECTION_AGE option without jitter
   would not create connection storms by itself, but if there happened to be a
   connection storm it could cause it to repeat at a fixed period. */
static grpc_millis
add_random_max_connection_age_jitter_and_convert_to_grpc_millis(int value) {
  /* generate a random number between 1 - MAX_CONNECTION_AGE_JITTER and
     1 + MAX_CONNECTION_AGE_JITTER */
  double multiplier = rand() * MAX_CONNECTION_AGE_JITTER * 2.0 / RAND_MAX +
                      1.0 - MAX_CONNECTION_AGE_JITTER;
  double result = multiplier * value;
  /* INT_MAX - 0.5 converts the value to float, so that result will not be
     cast to int implicitly before the comparison. */
  return result > (static_cast<double>(GRPC_MILLIS_INF_FUTURE)) - 0.5
             ? GRPC_MILLIS_INF_FUTURE
             : static_cast<grpc_millis>(result);
}

/* Constructor for call_data. */
static grpc_error* init_call_elem(grpc_call_element* elem,
                                  const grpc_call_element_args* args) {
  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
  increase_call_count(chand);
  return GRPC_ERROR_NONE;
}

/* Destructor for call_data. */
static void destroy_call_elem(grpc_call_element* elem,
                              const grpc_call_final_info* final_info,
                              grpc_closure* ignored) {
  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
  decrease_call_count(chand);
}

/* Constructor for channel_data. */
static grpc_error* init_channel_elem(grpc_channel_element* elem,
                                     grpc_channel_element_args* args) {
  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
  gpr_mu_init(&chand->max_age_timer_mu);
  chand->max_age_timer_pending = false;
  chand->max_age_grace_timer_pending = false;
  chand->channel_stack = args->channel_stack;
  chand->max_connection_age =
      add_random_max_connection_age_jitter_and_convert_to_grpc_millis(
          DEFAULT_MAX_CONNECTION_AGE_MS);
  chand->max_connection_age_grace =
      DEFAULT_MAX_CONNECTION_AGE_GRACE_MS == INT_MAX
          ? GRPC_MILLIS_INF_FUTURE
          : DEFAULT_MAX_CONNECTION_AGE_GRACE_MS;
  chand->max_connection_idle = DEFAULT_MAX_CONNECTION_IDLE_MS == INT_MAX
                                   ? GRPC_MILLIS_INF_FUTURE
                                   : DEFAULT_MAX_CONNECTION_IDLE_MS;
  chand->idle_state = MAX_IDLE_STATE_INIT;
  gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, GPR_ATM_MIN);
  for (size_t i = 0; i < args->channel_args->num_args; ++i) {
    if (0 == strcmp(args->channel_args->args[i].key,
                    GRPC_ARG_MAX_CONNECTION_AGE_MS)) {
      const int value = grpc_channel_arg_get_integer(
          &args->channel_args->args[i], MAX_CONNECTION_AGE_INTEGER_OPTIONS);
      chand->max_connection_age =
          add_random_max_connection_age_jitter_and_convert_to_grpc_millis(
              value);
    } else if (0 == strcmp(args->channel_args->args[i].key,
                           GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS)) {
      const int value = grpc_channel_arg_get_integer(
          &args->channel_args->args[i],
          {DEFAULT_MAX_CONNECTION_AGE_GRACE_MS, 0, INT_MAX});
      chand->max_connection_age_grace =
          value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value;
    } else if (0 == strcmp(args->channel_args->args[i].key,
                           GRPC_ARG_MAX_CONNECTION_IDLE_MS)) {
      const int value = grpc_channel_arg_get_integer(
          &args->channel_args->args[i], MAX_CONNECTION_IDLE_INTEGER_OPTIONS);
      chand->max_connection_idle =
          value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value;
    }
  }
  GRPC_CLOSURE_INIT(&chand->max_idle_timer_cb, max_idle_timer_cb, chand,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&chand->close_max_age_channel, close_max_age_channel, chand,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&chand->force_close_max_age_channel,
                    force_close_max_age_channel, chand,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&chand->start_max_idle_timer_after_init,
                    start_max_idle_timer_after_init, chand,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&chand->start_max_age_timer_after_init,
                    start_max_age_timer_after_init, chand,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&chand->start_max_age_grace_timer_after_goaway_op,
                    start_max_age_grace_timer_after_goaway_op, chand,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&chand->channel_connectivity_changed,
                    channel_connectivity_changed, chand,
                    grpc_schedule_on_exec_ctx);

  if (chand->max_connection_age != GRPC_MILLIS_INF_FUTURE) {
    /* When the channel reaches its max age, we send down an op with
       goaway_error set.  However, we can't send down any ops until after the
       channel stack is fully initialized.  If we start the timer here, we have
       no guarantee that the timer won't pop before channel stack initialization
       is finished.  To avoid that problem, we create a closure to start the
       timer, and we schedule that closure to be run after call stack
       initialization is done. */
    GRPC_CHANNEL_STACK_REF(chand->channel_stack,
                           "max_age start_max_age_timer_after_init");
    GRPC_CLOSURE_SCHED(&chand->start_max_age_timer_after_init, GRPC_ERROR_NONE);
  }

  /* Initialize the number of calls as 1, so that the max_idle_timer will not
     start until start_max_idle_timer_after_init is invoked. */
  gpr_atm_rel_store(&chand->call_count, 1);
  if (chand->max_connection_idle != GRPC_MILLIS_INF_FUTURE) {
    GRPC_CHANNEL_STACK_REF(chand->channel_stack,
                           "max_age start_max_idle_timer_after_init");
    GRPC_CLOSURE_SCHED(&chand->start_max_idle_timer_after_init,
                       GRPC_ERROR_NONE);
  }
  return GRPC_ERROR_NONE;
}

/* Destructor for channel_data. */
static void destroy_channel_elem(grpc_channel_element* elem) {}

const grpc_channel_filter grpc_max_age_filter = {
    grpc_call_next_op,
    grpc_channel_next_op,
    0, /* sizeof_call_data */
    init_call_elem,
    grpc_call_stack_ignore_set_pollset_or_pollset_set,
    destroy_call_elem,
    sizeof(channel_data),
    init_channel_elem,
    destroy_channel_elem,
    grpc_channel_next_get_info,
    "max_age"};

static bool maybe_add_max_age_filter(grpc_channel_stack_builder* builder,
                                     void* arg) {
  const grpc_channel_args* channel_args =
      grpc_channel_stack_builder_get_channel_arguments(builder);
  bool enable =
      grpc_channel_arg_get_integer(
          grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_AGE_MS),
          MAX_CONNECTION_AGE_INTEGER_OPTIONS) != INT_MAX ||
      grpc_channel_arg_get_integer(
          grpc_channel_args_find(channel_args, GRPC_ARG_MAX_CONNECTION_IDLE_MS),
          MAX_CONNECTION_IDLE_INTEGER_OPTIONS) != INT_MAX;
  if (enable) {
    return grpc_channel_stack_builder_prepend_filter(
        builder, &grpc_max_age_filter, nullptr, nullptr);
  } else {
    return true;
  }
}

void grpc_max_age_filter_init(void) {
  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
                                   maybe_add_max_age_filter, nullptr);
}

void grpc_max_age_filter_shutdown(void) {}
