/*
 *
 * 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 "test/core/end2end/end2end_tests.h"

#include <string.h>

#include "src/core/channel/channel_args.h"
#include "src/core/channel/client_channel.h"
#include "src/core/channel/client_uchannel.h"
#include "src/core/channel/connected_channel.h"
#include "src/core/channel/http_client_filter.h"
#include "src/core/channel/http_server_filter.h"
#include "src/core/client_config/resolver_registry.h"
#include "src/core/iomgr/tcp_client.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/server.h"
#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"

typedef struct {
  grpc_connector base;
  gpr_refcount refs;

  grpc_closure *notify;
  grpc_connect_in_args args;
  grpc_connect_out_args *result;

  grpc_endpoint *tcp;

  grpc_closure connected;
} connector;

static void connector_ref(grpc_connector *con) {
  connector *c = (connector *)con;
  gpr_ref(&c->refs);
}

static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
  connector *c = (connector *)con;
  if (gpr_unref(&c->refs)) {
    gpr_free(c);
  }
}

static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
  connector *c = arg;
  grpc_closure *notify;
  grpc_endpoint *tcp = c->tcp;
  if (tcp != NULL) {
    c->result->transport =
        grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1);
    grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
                                        0);
    GPR_ASSERT(c->result->transport);
  } else {
    memset(c->result, 0, sizeof(*c->result));
  }
  notify = c->notify;
  c->notify = NULL;
  notify->cb(exec_ctx, notify->cb_arg, 1);
}

static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {}

static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con,
                              const grpc_connect_in_args *args,
                              grpc_connect_out_args *result,
                              grpc_closure *notify) {
  connector *c = (connector *)con;
  GPR_ASSERT(c->notify == NULL);
  GPR_ASSERT(notify->cb);
  c->notify = notify;
  c->args = *args;
  c->result = result;
  c->tcp = NULL;
  grpc_closure_init(&c->connected, connected, c);
  grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp,
                          args->interested_parties, args->addr, args->addr_len,
                          args->deadline);
}

static const grpc_connector_vtable connector_vtable = {
    connector_ref, connector_unref, connector_shutdown, connector_connect};

typedef struct {
  grpc_subchannel_factory base;
  gpr_refcount refs;
  grpc_channel_args *merge_args;
  grpc_channel *master;
  grpc_subchannel **sniffed_subchannel;
} subchannel_factory;

static void subchannel_factory_ref(grpc_subchannel_factory *scf) {
  subchannel_factory *f = (subchannel_factory *)scf;
  gpr_ref(&f->refs);
}

static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
                                     grpc_subchannel_factory *scf) {
  subchannel_factory *f = (subchannel_factory *)scf;
  if (gpr_unref(&f->refs)) {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
    grpc_channel_args_destroy(f->merge_args);
    gpr_free(f);
  }
}

static grpc_subchannel *subchannel_factory_create_subchannel(
    grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
    grpc_subchannel_args *args) {
  subchannel_factory *f = (subchannel_factory *)scf;
  connector *c = gpr_malloc(sizeof(*c));
  grpc_channel_args *final_args =
      grpc_channel_args_merge(args->args, f->merge_args);
  grpc_subchannel *s;
  memset(c, 0, sizeof(*c));
  c->base.vtable = &connector_vtable;
  gpr_ref_init(&c->refs, 1);
  args->args = final_args;
  s = grpc_subchannel_create(exec_ctx, &c->base, args);
  grpc_connector_unref(exec_ctx, &c->base);
  grpc_channel_args_destroy(final_args);
  if (*f->sniffed_subchannel) {
    GRPC_SUBCHANNEL_UNREF(exec_ctx, *f->sniffed_subchannel, "sniffed");
  }
  *f->sniffed_subchannel = s;
  GRPC_SUBCHANNEL_REF(s, "sniffed");
  return s;
}

static const grpc_subchannel_factory_vtable test_subchannel_factory_vtable = {
    subchannel_factory_ref, subchannel_factory_unref,
    subchannel_factory_create_subchannel};

/* The evil twin of grpc_insecure_channel_create. It allows the test to use the
 * custom-built sniffing subchannel_factory */
grpc_channel *channel_create(const char *target, const grpc_channel_args *args,
                             grpc_subchannel **sniffed_subchannel) {
  grpc_channel *channel = NULL;
  grpc_resolver *resolver;
  subchannel_factory *f;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  channel =
      grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);

  f = gpr_malloc(sizeof(*f));
  f->sniffed_subchannel = sniffed_subchannel;
  f->base.vtable = &test_subchannel_factory_vtable;
  gpr_ref_init(&f->refs, 1);
  f->merge_args = grpc_channel_args_copy(args);
  f->master = channel;
  GRPC_CHANNEL_INTERNAL_REF(f->master, "test_subchannel_factory");
  resolver = grpc_resolver_create(target, &f->base);
  if (!resolver) {
    return NULL;
  }

  grpc_client_channel_set_resolver(
      &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_create");
  grpc_subchannel_factory_unref(&exec_ctx, &f->base);

  grpc_exec_ctx_finish(&exec_ctx);

  return channel;
}

typedef struct micro_fullstack_fixture_data {
  char *localaddr;
  grpc_channel *master_channel;
  grpc_subchannel *sniffed_subchannel;
} micro_fullstack_fixture_data;

static grpc_end2end_test_fixture chttp2_create_fixture_micro_fullstack(
    grpc_channel_args *client_args, grpc_channel_args *server_args) {
  grpc_end2end_test_fixture f;
  int port = grpc_pick_unused_port_or_die();
  micro_fullstack_fixture_data *ffd =
      gpr_malloc(sizeof(micro_fullstack_fixture_data));
  memset(&f, 0, sizeof(f));
  memset(ffd, 0, sizeof(*ffd));

  gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port);

  f.fixture_data = ffd;
  f.cq = grpc_completion_queue_create(NULL);

  return f;
}

grpc_connectivity_state g_state = GRPC_CHANNEL_IDLE;
grpc_pollset_set g_interested_parties;

static void state_changed(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
  if (g_state != GRPC_CHANNEL_READY) {
    grpc_subchannel_notify_on_state_change(
        exec_ctx, arg, &g_interested_parties, &g_state,
        grpc_closure_create(state_changed, arg));
  }
}

static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
  grpc_pollset_destroy(arg);
}

static grpc_connected_subchannel *connect_subchannel(grpc_subchannel *c) {
  grpc_pollset pollset;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_pollset_init(&pollset);
  grpc_pollset_set_init(&g_interested_parties);
  grpc_pollset_set_add_pollset(&exec_ctx, &g_interested_parties, &pollset);
  grpc_subchannel_notify_on_state_change(&exec_ctx, c, &g_interested_parties,
                                         &g_state,
                                         grpc_closure_create(state_changed, c));
  grpc_exec_ctx_flush(&exec_ctx);
  gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
  while (g_state != GRPC_CHANNEL_READY) {
    grpc_pollset_worker worker;
    grpc_pollset_work(&exec_ctx, &pollset, &worker,
                      gpr_now(GPR_CLOCK_MONOTONIC),
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
    gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
    grpc_exec_ctx_flush(&exec_ctx);
    gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
  }
  grpc_pollset_shutdown(&exec_ctx, &pollset,
                        grpc_closure_create(destroy_pollset, &pollset));
  grpc_pollset_set_destroy(&g_interested_parties);
  gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
  grpc_exec_ctx_finish(&exec_ctx);
  return grpc_subchannel_get_connected_subchannel(c);
}

static void chttp2_init_client_micro_fullstack(grpc_end2end_test_fixture *f,
                                               grpc_channel_args *client_args) {
  micro_fullstack_fixture_data *ffd = f->fixture_data;
  grpc_connectivity_state conn_state;
  grpc_connected_subchannel *connected;
  char *ipv4_localaddr;

  gpr_asprintf(&ipv4_localaddr, "ipv4:%s", ffd->localaddr);
  ffd->master_channel =
      channel_create(ipv4_localaddr, client_args, &ffd->sniffed_subchannel);
  gpr_free(ipv4_localaddr);
  gpr_log(GPR_INFO, "MASTER CHANNEL %p ", ffd->master_channel);
  /* the following will block. That's ok for this test */
  conn_state = grpc_channel_check_connectivity_state(ffd->master_channel,
                                                     1 /* try to connect */);
  GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE);

  /* here sniffed_subchannel should be ready to use */
  GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE);
  GPR_ASSERT(ffd->sniffed_subchannel != NULL);

  connected = connect_subchannel(ffd->sniffed_subchannel);
  f->client = grpc_client_uchannel_create(ffd->sniffed_subchannel, client_args);
  grpc_client_uchannel_set_connected_subchannel(f->client, connected);
  gpr_log(GPR_INFO, "CHANNEL WRAPPING SUBCHANNEL: %p(%p)", f->client,
          ffd->sniffed_subchannel);

  GPR_ASSERT(f->client);
}

static void chttp2_init_server_micro_fullstack(grpc_end2end_test_fixture *f,
                                               grpc_channel_args *server_args) {
  micro_fullstack_fixture_data *ffd = f->fixture_data;
  if (f->server) {
    grpc_server_destroy(f->server);
  }
  f->server = grpc_server_create(server_args, NULL);
  grpc_server_register_completion_queue(f->server, f->cq, NULL);
  GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
  grpc_server_start(f->server);
}

static void chttp2_tear_down_micro_fullstack(grpc_end2end_test_fixture *f) {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  micro_fullstack_fixture_data *ffd = f->fixture_data;
  grpc_channel_destroy(ffd->master_channel);
  if (ffd->sniffed_subchannel) {
    GRPC_SUBCHANNEL_UNREF(&exec_ctx, ffd->sniffed_subchannel, "sniffed");
  }
  gpr_free(ffd->localaddr);
  gpr_free(ffd);
  grpc_exec_ctx_finish(&exec_ctx);
}

/* All test configurations */
static grpc_end2end_test_config configs[] = {
    {"chttp2/micro_fullstack", 0, chttp2_create_fixture_micro_fullstack,
     chttp2_init_client_micro_fullstack, chttp2_init_server_micro_fullstack,
     chttp2_tear_down_micro_fullstack},
};

int main(int argc, char **argv) {
  size_t i;

  grpc_test_init(argc, argv);
  grpc_init();

  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
    grpc_end2end_tests(argc, argv, configs[i]);
  }

  grpc_shutdown();

  return 0;
}
