/*
 *
 * Copyright 2018 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/support/port_platform.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

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

#include "src/core/ext/filters/http/client_authority_filter.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/transport/static_metadata.h"

namespace {

struct call_data {
  grpc_linked_mdelem authority_storage;
  grpc_call_combiner* call_combiner;
};

struct channel_data {
  grpc_slice default_authority;
};

void authority_start_transport_stream_op_batch(
    grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
  call_data* calld = static_cast<call_data*>(elem->call_data);
  // Handle send_initial_metadata.
  auto* initial_metadata =
      batch->payload->send_initial_metadata.send_initial_metadata;
  // If the initial metadata doesn't already contain :authority, add it.
  if (batch->send_initial_metadata &&
      initial_metadata->idx.named.authority == nullptr) {
    grpc_error* error = grpc_metadata_batch_add_head(
        initial_metadata, &calld->authority_storage,
        grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, chand->default_authority,
                           nullptr));
    if (error != GRPC_ERROR_NONE) {
      grpc_transport_stream_op_batch_finish_with_failure(batch, error,
                                                         calld->call_combiner);
      return;
    }
  }
  // Pass control down the stack.
  grpc_call_next_op(elem, batch);
}

/* Constructor for call_data */
grpc_error* init_call_elem(grpc_call_element* elem,
                           const grpc_call_element_args* args) {
  call_data* calld = static_cast<call_data*>(elem->call_data);
  calld->call_combiner = args->call_combiner;
  return GRPC_ERROR_NONE;
}

/* Destructor for call_data */
void destroy_call_elem(grpc_call_element* elem,
                       const grpc_call_final_info* final_info,
                       grpc_closure* ignored) {}

/* Constructor for channel_data */
grpc_error* init_channel_elem(grpc_channel_element* elem,
                              grpc_channel_element_args* args) {
  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
  const grpc_arg* default_authority_arg =
      grpc_channel_args_find(args->channel_args, GRPC_ARG_DEFAULT_AUTHORITY);
  if (default_authority_arg == nullptr) {
    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
        "GRPC_ARG_DEFAULT_AUTHORITY channel arg. not found. Note that direct "
        "channels must explicitly specify a value for this argument.");
  }
  const char* default_authority_str =
      grpc_channel_arg_get_string(default_authority_arg);
  if (default_authority_str == nullptr) {
    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
        "GRPC_ARG_DEFAULT_AUTHORITY channel arg. must be a string");
  }
  chand->default_authority =
      grpc_slice_intern(grpc_slice_from_static_string(default_authority_str));
  GPR_ASSERT(!args->is_last);
  return GRPC_ERROR_NONE;
}

/* Destructor for channel data */
void destroy_channel_elem(grpc_channel_element* elem) {
  channel_data* chand = static_cast<channel_data*>(elem->channel_data);
  grpc_slice_unref_internal(chand->default_authority);
}
}  // namespace

const grpc_channel_filter grpc_client_authority_filter = {
    authority_start_transport_stream_op_batch,
    grpc_channel_next_op,
    sizeof(call_data),
    init_call_elem,
    grpc_call_stack_ignore_set_pollset_or_pollset_set,
    destroy_call_elem,
    sizeof(channel_data),
    init_channel_elem,
    destroy_channel_elem,
    grpc_channel_next_get_info,
    "authority"};

static bool add_client_authority_filter(grpc_channel_stack_builder* builder,
                                        void* arg) {
  const grpc_channel_args* channel_args =
      grpc_channel_stack_builder_get_channel_arguments(builder);
  const grpc_arg* disable_client_authority_filter_arg = grpc_channel_args_find(
      channel_args, GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER);
  if (disable_client_authority_filter_arg != nullptr) {
    const bool is_client_authority_filter_disabled =
        grpc_channel_arg_get_bool(disable_client_authority_filter_arg, false);
    if (is_client_authority_filter_disabled) {
      return true;
    }
  }
  return grpc_channel_stack_builder_prepend_filter(
      builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr);
}

void grpc_client_authority_filter_init(void) {
  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
                                   add_client_authority_filter,
                                   (void*)&grpc_client_authority_filter);
  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
                                   add_client_authority_filter,
                                   (void*)&grpc_client_authority_filter);
}

void grpc_client_authority_filter_shutdown(void) {}
