/*
 *
 * Copyright 2015-2016, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "src/core/surface/channel.h"

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>

#include "src/core/channel/client_channel.h"
#include "src/core/channel/client_uchannel.h"
#include "src/core/iomgr/timer.h"
#include "src/core/surface/api_trace.h"
#include "src/core/surface/completion_queue.h"

grpc_connectivity_state grpc_channel_check_connectivity_state(
    grpc_channel *channel, int try_to_connect) {
  /* forward through to the underlying client channel */
  grpc_channel_element *client_channel_elem =
      grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_connectivity_state state;
  GRPC_API_TRACE(
      "grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2,
      (channel, try_to_connect));
  if (client_channel_elem->filter == &grpc_client_channel_filter) {
    state = grpc_client_channel_check_connectivity_state(
        &exec_ctx, client_channel_elem, try_to_connect);
    grpc_exec_ctx_finish(&exec_ctx);
    return state;
  }
  if (client_channel_elem->filter == &grpc_client_uchannel_filter) {
    state = grpc_client_uchannel_check_connectivity_state(
        &exec_ctx, client_channel_elem, try_to_connect);
    grpc_exec_ctx_finish(&exec_ctx);
    return state;
  }
  gpr_log(GPR_ERROR,
          "grpc_channel_check_connectivity_state called on something that is "
          "not a (u)client channel, but '%s'",
          client_channel_elem->filter->name);
  grpc_exec_ctx_finish(&exec_ctx);
  return GRPC_CHANNEL_FATAL_FAILURE;
}

typedef enum {
  WAITING,
  CALLING_BACK,
  CALLING_BACK_AND_FINISHED,
  CALLED_BACK
} callback_phase;

typedef struct {
  gpr_mu mu;
  callback_phase phase;
  int success;
  grpc_closure on_complete;
  grpc_timer alarm;
  grpc_connectivity_state state;
  grpc_completion_queue *cq;
  grpc_cq_completion completion_storage;
  grpc_channel *channel;
  void *tag;
} state_watcher;

static void delete_state_watcher(grpc_exec_ctx *exec_ctx, state_watcher *w) {
  grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element(
      grpc_channel_get_channel_stack(w->channel));
  if (client_channel_elem->filter == &grpc_client_channel_filter) {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel,
                                "watch_channel_connectivity");
  } else if (client_channel_elem->filter == &grpc_client_uchannel_filter) {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel,
                                "watch_uchannel_connectivity");
  } else {
    abort();
  }
  gpr_mu_destroy(&w->mu);
  gpr_free(w);
}

static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw,
                                grpc_cq_completion *ignored) {
  int delete = 0;
  state_watcher *w = pw;
  gpr_mu_lock(&w->mu);
  switch (w->phase) {
    case WAITING:
    case CALLED_BACK:
      GPR_UNREACHABLE_CODE(return );
    case CALLING_BACK:
      w->phase = CALLED_BACK;
      break;
    case CALLING_BACK_AND_FINISHED:
      delete = 1;
      break;
  }
  gpr_mu_unlock(&w->mu);

  if (delete) {
    delete_state_watcher(exec_ctx, w);
  }
}

static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
                        int due_to_completion) {
  int delete = 0;

  if (due_to_completion) {
    grpc_timer_cancel(exec_ctx, &w->alarm);
  }

  gpr_mu_lock(&w->mu);
  if (due_to_completion) {
    w->success = 1;
  }
  switch (w->phase) {
    case WAITING:
      w->phase = CALLING_BACK;
      grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->success, finished_completion,
                     w, &w->completion_storage);
      break;
    case CALLING_BACK:
      w->phase = CALLING_BACK_AND_FINISHED;
      break;
    case CALLING_BACK_AND_FINISHED:
      GPR_UNREACHABLE_CODE(return );
    case CALLED_BACK:
      delete = 1;
      break;
  }
  gpr_mu_unlock(&w->mu);

  if (delete) {
    delete_state_watcher(exec_ctx, w);
  }
}

static void watch_complete(grpc_exec_ctx *exec_ctx, void *pw, bool success) {
  partly_done(exec_ctx, pw, 1);
}

static void timeout_complete(grpc_exec_ctx *exec_ctx, void *pw, bool success) {
  partly_done(exec_ctx, pw, 0);
}

void grpc_channel_watch_connectivity_state(
    grpc_channel *channel, grpc_connectivity_state last_observed_state,
    gpr_timespec deadline, grpc_completion_queue *cq, void *tag) {
  grpc_channel_element *client_channel_elem =
      grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  state_watcher *w = gpr_malloc(sizeof(*w));

  GRPC_API_TRACE(
      "grpc_channel_watch_connectivity_state("
      "channel=%p, last_observed_state=%d, "
      "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
      "cq=%p, tag=%p)",
      7, (channel, (int)last_observed_state, (long long)deadline.tv_sec,
          (int)deadline.tv_nsec, (int)deadline.clock_type, cq, tag));

  grpc_cq_begin_op(cq, tag);

  gpr_mu_init(&w->mu);
  grpc_closure_init(&w->on_complete, watch_complete, w);
  w->phase = WAITING;
  w->state = last_observed_state;
  w->success = 0;
  w->cq = cq;
  w->tag = tag;
  w->channel = channel;

  grpc_timer_init(&exec_ctx, &w->alarm,
                  gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
                  timeout_complete, w, gpr_now(GPR_CLOCK_MONOTONIC));

  if (client_channel_elem->filter == &grpc_client_channel_filter) {
    GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");
    grpc_client_channel_watch_connectivity_state(&exec_ctx, client_channel_elem,
                                                 grpc_cq_pollset(cq), &w->state,
                                                 &w->on_complete);
  } else if (client_channel_elem->filter == &grpc_client_uchannel_filter) {
    GRPC_CHANNEL_INTERNAL_REF(channel, "watch_uchannel_connectivity");
    grpc_client_uchannel_watch_connectivity_state(
        &exec_ctx, client_channel_elem, grpc_cq_pollset(cq), &w->state,
        &w->on_complete);
  }

  grpc_exec_ctx_finish(&exec_ctx);
}
