/*
 *
 * Copyright 2015 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 <ruby/ruby.h>

#include "rb_call_credentials.h"
#include "rb_grpc_imports.generated.h"

#include <ruby/thread.h>

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

#include "rb_call.h"
#include "rb_event_thread.h"
#include "rb_grpc.h"

/* grpc_rb_cCallCredentials is the ruby class that proxies
 * grpc_call_credentials */
static VALUE grpc_rb_cCallCredentials = Qnil;

/* grpc_rb_call_credentials wraps a grpc_call_credentials. It provides a mark
 * object that is used to hold references to any objects used to create the
 * credentials. */
typedef struct grpc_rb_call_credentials {
  /* Holder of ruby objects involved in contructing the credentials */
  VALUE mark;

  /* The actual credentials */
  grpc_call_credentials* wrapped;
} grpc_rb_call_credentials;

typedef struct callback_params {
  VALUE get_metadata;
  grpc_auth_metadata_context context;
  void* user_data;
  grpc_credentials_plugin_metadata_cb callback;
} callback_params;

static VALUE grpc_rb_call_credentials_callback(VALUE callback_args) {
  VALUE result = rb_hash_new();
  VALUE metadata = rb_funcall(rb_ary_entry(callback_args, 0), rb_intern("call"),
                              1, rb_ary_entry(callback_args, 1));
  rb_hash_aset(result, rb_str_new2("metadata"), metadata);
  rb_hash_aset(result, rb_str_new2("status"), INT2NUM(GRPC_STATUS_OK));
  rb_hash_aset(result, rb_str_new2("details"), rb_str_new2(""));
  return result;
}

static VALUE grpc_rb_call_credentials_callback_rescue(VALUE args,
                                                      VALUE exception_object) {
  VALUE result = rb_hash_new();
  VALUE backtrace =
      rb_funcall(rb_funcall(exception_object, rb_intern("backtrace"), 0),
                 rb_intern("join"), 1, rb_str_new2("\n\tfrom "));
  VALUE rb_exception_info =
      rb_funcall(exception_object, rb_intern("inspect"), 0);
  (void)args;
  gpr_log(GPR_INFO, "Call credentials callback failed: %s\n%s",
          StringValueCStr(rb_exception_info), StringValueCStr(backtrace));
  rb_hash_aset(result, rb_str_new2("metadata"), Qnil);
  rb_hash_aset(result, rb_str_new2("status"),
               INT2NUM(GRPC_STATUS_UNAUTHENTICATED));
  rb_hash_aset(result, rb_str_new2("details"), rb_exception_info);
  return result;
}

static void grpc_rb_call_credentials_callback_with_gil(void* param) {
  callback_params* const params = (callback_params*)param;
  VALUE auth_uri = rb_str_new_cstr(params->context.service_url);
  /* Pass the arguments to the proc in a hash, which currently only has they key
     'auth_uri' */
  VALUE callback_args = rb_ary_new();
  VALUE args = rb_hash_new();
  VALUE result;
  grpc_metadata_array md_ary;
  grpc_status_code status;
  VALUE details;
  char* error_details;
  grpc_metadata_array_init(&md_ary);
  rb_hash_aset(args, ID2SYM(rb_intern("jwt_aud_uri")), auth_uri);
  rb_ary_push(callback_args, params->get_metadata);
  rb_ary_push(callback_args, args);
  result = rb_rescue(grpc_rb_call_credentials_callback, callback_args,
                     grpc_rb_call_credentials_callback_rescue, Qnil);
  // Both callbacks return a hash, so result should be a hash
  grpc_rb_md_ary_convert(rb_hash_aref(result, rb_str_new2("metadata")),
                         &md_ary);
  status = NUM2INT(rb_hash_aref(result, rb_str_new2("status")));
  details = rb_hash_aref(result, rb_str_new2("details"));
  error_details = StringValueCStr(details);
  params->callback(params->user_data, md_ary.metadata, md_ary.count, status,
                   error_details);
  grpc_rb_metadata_array_destroy_including_entries(&md_ary);
  gpr_free(params);
}

static int grpc_rb_call_credentials_plugin_get_metadata(
    void* state, grpc_auth_metadata_context context,
    grpc_credentials_plugin_metadata_cb cb, void* user_data,
    grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
    size_t* num_creds_md, grpc_status_code* status,
    const char** error_details) {
  callback_params* params = gpr_malloc(sizeof(callback_params));
  params->get_metadata = (VALUE)state;
  params->context = context;
  params->user_data = user_data;
  params->callback = cb;

  grpc_rb_event_queue_enqueue(grpc_rb_call_credentials_callback_with_gil,
                              (void*)(params));
  return 0;  // Async return.
}

static void grpc_rb_call_credentials_plugin_destroy(void* state) {
  (void)state;
  // Not sure what needs to be done here
}

static void grpc_rb_call_credentials_free_internal(void* p) {
  grpc_rb_call_credentials* wrapper;
  if (p == NULL) {
    return;
  }
  wrapper = (grpc_rb_call_credentials*)p;
  grpc_call_credentials_release(wrapper->wrapped);
  wrapper->wrapped = NULL;
  xfree(p);
}

/* Destroys the credentials instances. */
static void grpc_rb_call_credentials_free(void* p) {
  grpc_rb_call_credentials_free_internal(p);
  grpc_ruby_shutdown();
}

/* Protects the mark object from GC */
static void grpc_rb_call_credentials_mark(void* p) {
  grpc_rb_call_credentials* wrapper = NULL;
  if (p == NULL) {
    return;
  }
  wrapper = (grpc_rb_call_credentials*)p;
  if (wrapper->mark != Qnil) {
    rb_gc_mark(wrapper->mark);
  }
}

static rb_data_type_t grpc_rb_call_credentials_data_type = {
    "grpc_call_credentials",
    {grpc_rb_call_credentials_mark,
     grpc_rb_call_credentials_free,
     GRPC_RB_MEMSIZE_UNAVAILABLE,
     {NULL, NULL}},
    NULL,
    NULL,
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
    RUBY_TYPED_FREE_IMMEDIATELY
#endif
};

/* Allocates CallCredentials instances.
   Provides safe initial defaults for the instance fields. */
static VALUE grpc_rb_call_credentials_alloc(VALUE cls) {
  grpc_ruby_init();
  grpc_rb_call_credentials* wrapper = ALLOC(grpc_rb_call_credentials);
  wrapper->wrapped = NULL;
  wrapper->mark = Qnil;
  return TypedData_Wrap_Struct(cls, &grpc_rb_call_credentials_data_type,
                               wrapper);
}

/* Creates a wrapping object for a given call credentials. This should only be
 * called with grpc_call_credentials objects that are not already associated
 * with any Ruby object */
VALUE grpc_rb_wrap_call_credentials(grpc_call_credentials* c, VALUE mark) {
  VALUE rb_wrapper;
  grpc_rb_call_credentials* wrapper;
  if (c == NULL) {
    return Qnil;
  }
  rb_wrapper = grpc_rb_call_credentials_alloc(grpc_rb_cCallCredentials);
  TypedData_Get_Struct(rb_wrapper, grpc_rb_call_credentials,
                       &grpc_rb_call_credentials_data_type, wrapper);
  wrapper->wrapped = c;
  wrapper->mark = mark;
  return rb_wrapper;
}

/* The attribute used on the mark object to hold the callback */
static ID id_callback;

/*
  call-seq:
    creds = Credentials.new auth_proc
  proc: (required) Proc that generates auth metadata
  Initializes CallCredential instances. */
static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) {
  grpc_rb_call_credentials* wrapper = NULL;
  grpc_call_credentials* creds = NULL;
  grpc_metadata_credentials_plugin plugin;

  TypedData_Get_Struct(self, grpc_rb_call_credentials,
                       &grpc_rb_call_credentials_data_type, wrapper);

  plugin.get_metadata = grpc_rb_call_credentials_plugin_get_metadata;
  plugin.destroy = grpc_rb_call_credentials_plugin_destroy;
  if (!rb_obj_is_proc(proc)) {
    rb_raise(rb_eTypeError, "Argument to CallCredentials#new must be a proc");
    return Qnil;
  }
  plugin.state = (void*)proc;
  plugin.type = "";

  creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
  if (creds == NULL) {
    rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
    return Qnil;
  }

  wrapper->mark = proc;
  wrapper->wrapped = creds;
  rb_ivar_set(self, id_callback, proc);

  return self;
}

static VALUE grpc_rb_call_credentials_compose(int argc, VALUE* argv,
                                              VALUE self) {
  grpc_call_credentials* creds;
  grpc_call_credentials* other;
  grpc_call_credentials* prev = NULL;
  VALUE mark;
  if (argc == 0) {
    return self;
  }
  mark = rb_ary_new();
  creds = grpc_rb_get_wrapped_call_credentials(self);
  for (int i = 0; i < argc; i++) {
    rb_ary_push(mark, argv[i]);
    other = grpc_rb_get_wrapped_call_credentials(argv[i]);
    creds = grpc_composite_call_credentials_create(creds, other, NULL);
    if (prev != NULL) {
      grpc_call_credentials_release(prev);
    }
    prev = creds;
  }
  return grpc_rb_wrap_call_credentials(creds, mark);
}

void Init_grpc_call_credentials() {
  grpc_rb_cCallCredentials =
      rb_define_class_under(grpc_rb_mGrpcCore, "CallCredentials", rb_cObject);

  /* Allocates an object managed by the ruby runtime */
  rb_define_alloc_func(grpc_rb_cCallCredentials,
                       grpc_rb_call_credentials_alloc);

  /* Provides a ruby constructor and support for dup/clone. */
  rb_define_method(grpc_rb_cCallCredentials, "initialize",
                   grpc_rb_call_credentials_init, 1);
  rb_define_method(grpc_rb_cCallCredentials, "initialize_copy",
                   grpc_rb_cannot_init_copy, 1);
  rb_define_method(grpc_rb_cCallCredentials, "compose",
                   grpc_rb_call_credentials_compose, -1);

  id_callback = rb_intern("__callback");
}

/* Gets the wrapped grpc_call_credentials from the ruby wrapper */
grpc_call_credentials* grpc_rb_get_wrapped_call_credentials(VALUE v) {
  grpc_rb_call_credentials* wrapper = NULL;
  TypedData_Get_Struct(v, grpc_rb_call_credentials,
                       &grpc_rb_call_credentials_data_type, wrapper);
  return wrapper->wrapped;
}
