/*
 *
 * 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/security/auth.h"

#include <string.h>

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

#include "src/core/support/string.h"
#include "src/core/channel/channel_stack.h"
#include "src/core/security/security_connector.h"
#include "src/core/security/credentials.h"
#include "src/core/surface/call.h"

#define MAX_CREDENTIALS_METADATA_COUNT 4

/* We can have a per-call credentials. */
typedef struct {
  grpc_credentials *creds;
  grpc_mdstr *host;
  grpc_mdstr *method;
  grpc_call_op op;
  grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
} call_data;

/* We can have a per-channel credentials. */
typedef struct {
  grpc_channel_security_connector *security_connector;
  grpc_mdctx *md_ctx;
  grpc_mdstr *authority_string;
  grpc_mdstr *path_string;
  grpc_mdstr *error_msg_key;
  grpc_mdstr *status_key;
} channel_data;

static void bubbleup_error(grpc_call_element *elem, const char *error_msg) {
  grpc_call_element_recv_status(elem, GRPC_STATUS_UNAUTHENTICATED, error_msg);
  grpc_call_element_send_cancel(elem);
}

static void on_credentials_metadata(void *user_data, grpc_mdelem **md_elems,
                                    size_t num_md,
                                    grpc_credentials_status status) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;
  grpc_call_op op = calld->op;
  size_t i;
  GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
  for (i = 0; i < num_md; i++) {
    grpc_metadata_batch_add_tail(&op.data.metadata, &calld->md_links[i],
                                 grpc_mdelem_ref(md_elems[i]));
  }
  grpc_call_next_op(elem, &op);
}

static char *build_service_url(const char *url_scheme, call_data *calld) {
  char *service_url;
  char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method));
  char *last_slash = strrchr(service, '/');
  if (last_slash == NULL) {
    gpr_log(GPR_ERROR, "No '/' found in fully qualified method name");
    service[0] = '\0';
  } else if (last_slash == service) {
    /* No service part in fully qualified method name: will just be "/". */
    service[1] = '\0';
  } else {
    *last_slash = '\0';
  }
  if (url_scheme == NULL) url_scheme = "";
  gpr_asprintf(&service_url, "%s://%s%s", url_scheme,
               grpc_mdstr_as_c_string(calld->host), service);
  gpr_free(service);
  return service_url;
}

static void send_security_metadata(grpc_call_element *elem, grpc_call_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *channeld = elem->channel_data;

  grpc_credentials *channel_creds =
      channeld->security_connector->request_metadata_creds;
  /* TODO(jboeuf):
     Decide on the policy in this case:
     - populate both channel and call?
     - the call takes precedence over the channel?
     - leave this decision up to the channel credentials?  */
  if (calld->creds != NULL) {
    gpr_log(GPR_ERROR, "Ignoring per call credentials for now.");
  }
  if (channel_creds != NULL &&
      grpc_credentials_has_request_metadata(channel_creds)) {
    char *service_url =
        build_service_url(channeld->security_connector->base.url_scheme, calld);
    calld->op = *op; /* Copy op (originates from the caller's stack). */
    grpc_credentials_get_request_metadata(channel_creds, service_url,
                                          on_credentials_metadata, elem);
    gpr_free(service_url);
  } else {
    grpc_call_next_op(elem, op);
  }
}

static void on_host_checked(void *user_data, grpc_security_status status) {
  grpc_call_element *elem = (grpc_call_element *)user_data;
  call_data *calld = elem->call_data;

  if (status == GRPC_SECURITY_OK) {
    send_security_metadata(elem, &calld->op);
  } else {
    char *error_msg;
    gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
                 grpc_mdstr_as_c_string(calld->host));
    bubbleup_error(elem, error_msg);
    grpc_metadata_batch_destroy(&calld->op.data.metadata);
    gpr_free(error_msg);
    calld->op.done_cb(calld->op.user_data, GRPC_OP_ERROR);
  }
}

/* Called either:
     - in response to an API call (or similar) from above, to send something
     - a network event (or similar) from below, to receive something
   op contains type and call direction information, in addition to the data
   that is being sent or received. */
static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
                    grpc_call_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *channeld = elem->channel_data;
  grpc_linked_mdelem *l;

  switch (op->type) {
    case GRPC_SEND_METADATA:
      for (l = op->data.metadata.list.head; l != NULL; l = l->next) {
        grpc_mdelem *md = l->md;
        /* Pointer comparison is OK for md_elems created from the same context.
         */
        if (md->key == channeld->authority_string) {
          if (calld->host != NULL) grpc_mdstr_unref(calld->host);
          calld->host = grpc_mdstr_ref(md->value);
        } else if (md->key == channeld->path_string) {
          if (calld->method != NULL) grpc_mdstr_unref(calld->method);
          calld->method = grpc_mdstr_ref(md->value);
        }
      }
      if (calld->host != NULL) {
        grpc_security_status status;
        const char *call_host = grpc_mdstr_as_c_string(calld->host);
        calld->op = *op; /* Copy op (originates from the caller's stack). */
        status = grpc_channel_security_connector_check_call_host(
            channeld->security_connector, call_host, on_host_checked, elem);
        if (status != GRPC_SECURITY_OK) {
          if (status == GRPC_SECURITY_ERROR) {
            char *error_msg;
            gpr_asprintf(&error_msg,
                         "Invalid host %s set in :authority metadata.",
                         call_host);
            bubbleup_error(elem, error_msg);
            grpc_metadata_batch_destroy(&calld->op.data.metadata);
            gpr_free(error_msg);
            op->done_cb(op->user_data, GRPC_OP_ERROR);
          }
          break;
        }
      }
      send_security_metadata(elem, op);
      break;
    default:
      /* pass control up or down the stack depending on op->dir */
      grpc_call_next_op(elem, op);
      break;
  }
}

/* Called on special channel events, such as disconnection or new incoming
   calls on the server */
static void channel_op(grpc_channel_element *elem,
                       grpc_channel_element *from_elem, grpc_channel_op *op) {
  grpc_channel_next_op(elem, op);
}

/* Constructor for call_data */
static void init_call_elem(grpc_call_element *elem,
                           const void *server_transport_data) {
  /* TODO(jboeuf):
     Find a way to pass-in the credentials from the caller here.  */
  call_data *calld = elem->call_data;
  calld->creds = NULL;
  calld->host = NULL;
  calld->method = NULL;
}

/* Destructor for call_data */
static void destroy_call_elem(grpc_call_element *elem) {
  call_data *calld = elem->call_data;
  if (calld->creds != NULL) {
    grpc_credentials_unref(calld->creds);
  }
  if (calld->host != NULL) {
    grpc_mdstr_unref(calld->host);
  }
  if (calld->method != NULL) {
    grpc_mdstr_unref(calld->method);
  }
}

/* Constructor for channel_data */
static void init_channel_elem(grpc_channel_element *elem,
                              const grpc_channel_args *args,
                              grpc_mdctx *metadata_context, int is_first,
                              int is_last) {
  grpc_security_connector *ctx = grpc_find_security_connector_in_args(args);
  /* grab pointers to our data from the channel element */
  channel_data *channeld = elem->channel_data;

  /* The first and the last filters tend to be implemented differently to
     handle the case that there's no 'next' filter to call on the up or down
     path */
  GPR_ASSERT(!is_first);
  GPR_ASSERT(!is_last);
  GPR_ASSERT(ctx != NULL);

  /* initialize members */
  GPR_ASSERT(ctx->is_client_side);
  channeld->security_connector =
      (grpc_channel_security_connector *)grpc_security_connector_ref(ctx);
  channeld->md_ctx = metadata_context;
  channeld->authority_string =
      grpc_mdstr_from_string(channeld->md_ctx, ":authority");
  channeld->path_string = grpc_mdstr_from_string(channeld->md_ctx, ":path");
  channeld->error_msg_key =
      grpc_mdstr_from_string(channeld->md_ctx, "grpc-message");
  channeld->status_key =
      grpc_mdstr_from_string(channeld->md_ctx, "grpc-status");
}

/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element *elem) {
  /* grab pointers to our data from the channel element */
  channel_data *channeld = elem->channel_data;
  grpc_channel_security_connector *ctx = channeld->security_connector;
  if (ctx != NULL) grpc_security_connector_unref(&ctx->base);
  if (channeld->authority_string != NULL) {
    grpc_mdstr_unref(channeld->authority_string);
  }
  if (channeld->error_msg_key != NULL) {
    grpc_mdstr_unref(channeld->error_msg_key);
  }
  if (channeld->status_key != NULL) {
    grpc_mdstr_unref(channeld->status_key);
  }
  if (channeld->path_string != NULL) {
    grpc_mdstr_unref(channeld->path_string);
  }
}

const grpc_channel_filter grpc_client_auth_filter = {
    call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
    sizeof(channel_data), init_channel_elem, destroy_channel_elem, "auth"};
