/*
 *
 * Copyright 2015, 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/iomgr/sockaddr.h"

#include <grpc/grpc.h>

#include <stdlib.h>
#include <string.h>

#include "src/core/channel/census_filter.h"
#include "src/core/channel/channel_args.h"
#include "src/core/channel/client_channel.h"
#include "src/core/channel/client_setup.h"
#include "src/core/channel/connected_channel.h"
#include "src/core/channel/http_client_filter.h"
#include "src/core/channel/http_filter.h"
#include "src/core/iomgr/endpoint.h"
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/tcp_client.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/client.h"
#include "src/core/support/string.h"
#include "src/core/transport/chttp2_transport.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>

typedef struct setup setup;

/* A single setup request (started via initiate) */
typedef struct {
  grpc_client_setup_request *cs_request;
  setup *setup;
  /* Resolved addresses, or null if resolution not yet completed */
  grpc_resolved_addresses *resolved;
  /* which address in resolved should we pick for the next connection attempt */
  size_t resolved_index;
} request;

/* Global setup logic (may be running many simultaneous setup requests, but
   with only one 'active' */
struct setup {
  const char *target;
  grpc_transport_setup_callback setup_callback;
  void *setup_user_data;
};

static int maybe_try_next_resolved(request *r);

static void done(request *r, int was_successful) {
  grpc_client_setup_request_finish(r->cs_request, was_successful);
  if (r->resolved) {
    grpc_resolved_addresses_destroy(r->resolved);
  }
  gpr_free(r);
}

/* connection callback: tcp is either valid, or null on error */
static void on_connect(void *rp, grpc_endpoint *tcp) {
  request *r = rp;

  if (!grpc_client_setup_request_should_continue(r->cs_request)) {
    if (tcp) {
      grpc_endpoint_shutdown(tcp);
      grpc_endpoint_destroy(tcp);
    }
    done(r, 0);
    return;
  }

  if (!tcp) {
    if (!maybe_try_next_resolved(r)) {
      done(r, 0);
      return;
    } else {
      return;
    }
  } else if (grpc_client_setup_cb_begin(r->cs_request)) {
    grpc_create_chttp2_transport(
        r->setup->setup_callback, r->setup->setup_user_data,
        grpc_client_setup_get_channel_args(r->cs_request), tcp, NULL, 0,
        grpc_client_setup_get_mdctx(r->cs_request), 1);
    grpc_client_setup_cb_end(r->cs_request);
    done(r, 1);
    return;
  } else {
    done(r, 0);
  }
}

/* attempt to connect to the next available resolved address */
static int maybe_try_next_resolved(request *r) {
  grpc_resolved_address *addr;
  if (!r->resolved) return 0;
  if (r->resolved_index == r->resolved->naddrs) return 0;
  addr = &r->resolved->addrs[r->resolved_index++];
  grpc_tcp_client_connect(on_connect, r, (struct sockaddr *)&addr->addr,
                          addr->len,
                          grpc_client_setup_request_deadline(r->cs_request));
  return 1;
}

/* callback for when our target address has been resolved */
static void on_resolved(void *rp, grpc_resolved_addresses *resolved) {
  request *r = rp;

  /* if we're not still the active request, abort */
  if (!grpc_client_setup_request_should_continue(r->cs_request)) {
    if (resolved) {
      grpc_resolved_addresses_destroy(resolved);
    }
    done(r, 0);
    return;
  }

  if (!resolved) {
    done(r, 0);
    return;
  } else {
    r->resolved = resolved;
    r->resolved_index = 0;
    if (!maybe_try_next_resolved(r)) {
      done(r, 0);
    }
  }
}

static void initiate_setup(void *sp, grpc_client_setup_request *cs_request) {
  request *r = gpr_malloc(sizeof(request));
  r->setup = sp;
  r->cs_request = cs_request;
  r->resolved = NULL;
  r->resolved_index = 0;
  /* TODO(klempner): Make grpc_resolve_address respect deadline */
  grpc_resolve_address(r->setup->target, "http", on_resolved, r);
}

static void done_setup(void *sp) {
  setup *s = sp;
  gpr_free((void *)s->target);
  gpr_free(s);
}

static grpc_transport_setup_result complete_setup(void *channel_stack,
                                                  grpc_transport *transport,
                                                  grpc_mdctx *mdctx) {
  static grpc_channel_filter const *extra_filters[] = {&grpc_http_client_filter,
                                                       &grpc_http_filter};
  return grpc_client_channel_transport_setup_complete(
      channel_stack, transport, extra_filters, GPR_ARRAY_SIZE(extra_filters),
      mdctx);
}

/* Create a client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_channel_create(const char *target,
                                  const grpc_channel_args *args) {
  setup *s = gpr_malloc(sizeof(setup));
  grpc_mdctx *mdctx = grpc_mdctx_create();
  grpc_channel *channel = NULL;
#define MAX_FILTERS 3
  const grpc_channel_filter *filters[MAX_FILTERS];
  int n = 0;
  filters[n++] = &grpc_client_surface_filter;
  if (grpc_channel_args_is_census_enabled(args)) {
    filters[n++] = &grpc_client_census_filter;
  }
  filters[n++] = &grpc_client_channel_filter;
  GPR_ASSERT(n <= MAX_FILTERS);
  channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1);

  s->target = gpr_strdup(target);
  s->setup_callback = complete_setup;
  s->setup_user_data = grpc_channel_get_channel_stack(channel);

  grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel),
                                      args, mdctx, initiate_setup, done_setup,
                                      s);

  return channel;
}
