/*
 *
 * 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 <grpc/grpc.h>

#include <string.h>

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/channel/http_server_filter.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/auth_filters.h"
#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"

typedef struct server_secure_state {
  grpc_server *server;
  grpc_tcp_server *tcp;
  grpc_server_security_connector *sc;
  grpc_server_credentials *creds;
  bool is_shutdown;
  gpr_mu mu;
  gpr_refcount refcount;
  grpc_closure destroy_closure;
  grpc_closure *destroy_callback;
} server_secure_state;

typedef struct server_secure_connect {
  server_secure_state *state;
  grpc_pollset *accepting_pollset;
  grpc_tcp_server_acceptor *acceptor;
  grpc_handshake_manager *handshake_mgr;
  // TODO(roth): Remove the following two fields when we eliminate
  // grpc_server_security_connector_do_handshake().
  gpr_timespec deadline;
  grpc_channel_args *args;
} server_secure_connect;

static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); }

static void state_unref(server_secure_state *state) {
  if (gpr_unref(&state->refcount)) {
    /* ensure all threads have unlocked */
    gpr_mu_lock(&state->mu);
    gpr_mu_unlock(&state->mu);
    /* clean up */
    GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server");
    grpc_server_credentials_unref(state->creds);
    gpr_free(state);
  }
}

static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
                                     grpc_security_status status,
                                     grpc_endpoint *secure_endpoint,
                                     grpc_auth_context *auth_context) {
  server_secure_connect *state = statep;
  if (status == GRPC_SECURITY_OK) {
    if (secure_endpoint) {
      gpr_mu_lock(&state->state->mu);
      if (!state->state->is_shutdown) {
        grpc_transport *transport = grpc_create_chttp2_transport(
            exec_ctx, grpc_server_get_channel_args(state->state->server),
            secure_endpoint, 0);
        grpc_arg args_to_add[2];
        args_to_add[0] = grpc_server_credentials_to_arg(state->state->creds);
        args_to_add[1] = grpc_auth_context_to_arg(auth_context);
        grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
            state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
        grpc_server_setup_transport(exec_ctx, state->state->server, transport,
                                    state->accepting_pollset, args_copy);
        grpc_channel_args_destroy(args_copy);
        grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
      } else {
        /* We need to consume this here, because the server may already have
         * gone away. */
        grpc_endpoint_destroy(exec_ctx, secure_endpoint);
      }
      gpr_mu_unlock(&state->state->mu);
    }
  } else {
    gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
  }
  grpc_channel_args_destroy(state->args);
  state_unref(state->state);
  gpr_free(state);
}

static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
                              grpc_channel_args *args,
                              gpr_slice_buffer *read_buffer, void *user_data,
                              grpc_error *error) {
  server_secure_connect *state = user_data;
  if (error != GRPC_ERROR_NONE) {
    const char *error_str = grpc_error_string(error);
    gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
    grpc_error_free_string(error_str);
    GRPC_ERROR_UNREF(error);
    grpc_channel_args_destroy(args);
    gpr_free(read_buffer);
    grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
    grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
    state_unref(state->state);
    gpr_free(state);
    return;
  }
  grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
  state->handshake_mgr = NULL;
  // TODO(roth, jboeuf): Convert security connector handshaking to use new
  // handshake API, and then move the code from on_secure_handshake_done()
  // into this function.
  state->args = args;
  grpc_server_security_connector_do_handshake(
      exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer,
      state->deadline, on_secure_handshake_done, state);
}

static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
                      grpc_pollset *accepting_pollset,
                      grpc_tcp_server_acceptor *acceptor) {
  server_secure_connect *state = gpr_malloc(sizeof(*state));
  state->state = statep;
  state_ref(state->state);
  state->accepting_pollset = accepting_pollset;
  state->acceptor = acceptor;
  state->handshake_mgr = grpc_handshake_manager_create();
  // TODO(roth): We should really get this timeout value from channel
  // args instead of hard-coding it.
  state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                                 gpr_time_from_seconds(120, GPR_TIMESPAN));
  grpc_handshake_manager_do_handshake(
      exec_ctx, state->handshake_mgr, tcp,
      grpc_server_get_channel_args(state->state->server), state->deadline,
      acceptor, on_handshake_done, state);
}

/* Server callback: start listening on our ports */
static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep,
                  grpc_pollset **pollsets, size_t pollset_count) {
  server_secure_state *state = statep;
  grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count,
                        on_accept, state);
}

static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep,
                         grpc_error *error) {
  server_secure_state *state = statep;
  if (state->destroy_callback != NULL) {
    state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
                                GRPC_ERROR_REF(error));
  }
  grpc_server_security_connector_shutdown(exec_ctx, state->sc);
  state_unref(state);
}

/* Server callback: destroy the tcp listener (so we don't generate further
   callbacks) */
static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep,
                    grpc_closure *callback) {
  server_secure_state *state = statep;
  grpc_tcp_server *tcp;
  gpr_mu_lock(&state->mu);
  state->is_shutdown = true;
  state->destroy_callback = callback;
  tcp = state->tcp;
  gpr_mu_unlock(&state->mu);
  grpc_tcp_server_shutdown_listeners(exec_ctx, tcp);
  grpc_tcp_server_unref(exec_ctx, tcp);
}

int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
                                      grpc_server_credentials *creds) {
  grpc_resolved_addresses *resolved = NULL;
  grpc_tcp_server *tcp = NULL;
  server_secure_state *state = NULL;
  size_t i;
  size_t count = 0;
  int port_num = -1;
  int port_temp;
  grpc_security_status status = GRPC_SECURITY_ERROR;
  grpc_server_security_connector *sc = NULL;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_error *err = GRPC_ERROR_NONE;
  grpc_error **errors = NULL;

  GRPC_API_TRACE(
      "grpc_server_add_secure_http2_port("
      "server=%p, addr=%s, creds=%p)",
      3, (server, addr, creds));

  /* create security context */
  if (creds == NULL) {
    err = GRPC_ERROR_CREATE(
        "No credentials specified for secure server port (creds==NULL)");
    goto error;
  }
  status = grpc_server_credentials_create_security_connector(creds, &sc);
  if (status != GRPC_SECURITY_OK) {
    char *msg;
    gpr_asprintf(&msg,
                 "Unable to create secure server with credentials of type %s.",
                 creds->type);
    err = grpc_error_set_int(GRPC_ERROR_CREATE(msg),
                             GRPC_ERROR_INT_SECURITY_STATUS, status);
    gpr_free(msg);
    goto error;
  }
  sc->channel_args = grpc_server_get_channel_args(server);

  /* resolve address */
  err = grpc_blocking_resolve_address(addr, "https", &resolved);
  if (err != GRPC_ERROR_NONE) {
    goto error;
  }
  state = gpr_malloc(sizeof(*state));
  memset(state, 0, sizeof(*state));
  grpc_closure_init(&state->destroy_closure, destroy_done, state);
  err = grpc_tcp_server_create(&state->destroy_closure,
                               grpc_server_get_channel_args(server), &tcp);
  if (err != GRPC_ERROR_NONE) {
    goto error;
  }

  state->server = server;
  state->tcp = tcp;
  state->sc = sc;
  state->creds = grpc_server_credentials_ref(creds);
  state->is_shutdown = false;
  gpr_mu_init(&state->mu);
  gpr_ref_init(&state->refcount, 1);

  errors = gpr_malloc(sizeof(*errors) * resolved->naddrs);
  for (i = 0; i < resolved->naddrs; i++) {
    errors[i] = grpc_tcp_server_add_port(
        tcp, (struct sockaddr *)&resolved->addrs[i].addr,
        resolved->addrs[i].len, &port_temp);
    if (errors[i] == GRPC_ERROR_NONE) {
      if (port_num == -1) {
        port_num = port_temp;
      } else {
        GPR_ASSERT(port_num == port_temp);
      }
      count++;
    }
  }
  if (count == 0) {
    char *msg;
    gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
                 resolved->naddrs);
    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, resolved->naddrs);
    gpr_free(msg);
    goto error;
  } else if (count != resolved->naddrs) {
    char *msg;
    gpr_asprintf(&msg, "Only %" PRIuPTR
                       " addresses added out of total %" PRIuPTR " resolved",
                 count, resolved->naddrs);
    err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, resolved->naddrs);
    gpr_free(msg);

    const char *warning_message = grpc_error_string(err);
    gpr_log(GPR_INFO, "WARNING: %s", warning_message);
    grpc_error_free_string(warning_message);
    /* we managed to bind some addresses: continue */
  } else {
    for (i = 0; i < resolved->naddrs; i++) {
      GRPC_ERROR_UNREF(errors[i]);
    }
  }
  gpr_free(errors);
  errors = NULL;
  grpc_resolved_addresses_destroy(resolved);

  /* Register with the server only upon success */
  grpc_server_add_listener(&exec_ctx, server, state, start, destroy);

  grpc_exec_ctx_finish(&exec_ctx);
  return port_num;

/* Error path: cleanup and return */
error:
  GPR_ASSERT(err != GRPC_ERROR_NONE);
  if (errors != NULL) {
    for (i = 0; i < resolved->naddrs; i++) {
      GRPC_ERROR_UNREF(errors[i]);
    }
    gpr_free(errors);
  }
  if (resolved) {
    grpc_resolved_addresses_destroy(resolved);
  }
  if (tcp) {
    grpc_tcp_server_unref(&exec_ctx, tcp);
  } else {
    if (sc) {
      GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
    }
    if (state) {
      gpr_free(state);
    }
  }
  grpc_exec_ctx_finish(&exec_ctx);
  const char *msg = grpc_error_string(err);
  GRPC_ERROR_UNREF(err);
  gpr_log(GPR_ERROR, "%s", msg);
  grpc_error_free_string(msg);
  return 0;
}
