/*
 *
 * 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_byte_buffer.h"
#include "rb_compression_options.h"
#include "rb_grpc_imports.generated.h"

#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <string.h>

#include "rb_grpc.h"

static VALUE grpc_rb_cCompressionOptions = Qnil;

/* Ruby Ids for the names of valid compression levels. */
static VALUE id_compress_level_none = Qnil;
static VALUE id_compress_level_low = Qnil;
static VALUE id_compress_level_medium = Qnil;
static VALUE id_compress_level_high = Qnil;

/* grpc_rb_compression_options wraps a grpc_compression_options.
 * It can be used to get the channel argument key-values for specific
 * compression settings. */

/* Note that ruby objects of this type don't carry any state in other
 * Ruby objects and don't have a mark for GC. */
typedef struct grpc_rb_compression_options {
  /* The actual compression options that's being wrapped */
  grpc_compression_options* wrapped;
} grpc_rb_compression_options;

static void grpc_rb_compression_options_free_internal(void* p) {
  grpc_rb_compression_options* wrapper = NULL;
  if (p == NULL) {
    return;
  };
  wrapper = (grpc_rb_compression_options*)p;
  if (wrapper->wrapped != NULL) {
    gpr_free(wrapper->wrapped);
    wrapper->wrapped = NULL;
  }
  xfree(p);
}

/* Destroys the compression options instances and free the
 * wrapped grpc compression options. */
static void grpc_rb_compression_options_free(void* p) {
  grpc_rb_compression_options_free_internal(p);
  grpc_ruby_shutdown();
}

/* Ruby recognized data type for the CompressionOptions class. */
static rb_data_type_t grpc_rb_compression_options_data_type = {
    "grpc_compression_options",
    {NULL,
     grpc_rb_compression_options_free,
     GRPC_RB_MEMSIZE_UNAVAILABLE,
     {NULL, NULL}},
    NULL,
    NULL,
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
    RUBY_TYPED_FREE_IMMEDIATELY
#endif
};

/* Allocates CompressionOptions instances.
   Allocate the wrapped grpc compression options and
   initialize it here too. */
static VALUE grpc_rb_compression_options_alloc(VALUE cls) {
  grpc_ruby_init();
  grpc_rb_compression_options* wrapper = NULL;

  wrapper = gpr_malloc(sizeof(grpc_rb_compression_options));
  wrapper->wrapped = NULL;
  wrapper->wrapped = gpr_malloc(sizeof(grpc_compression_options));
  grpc_compression_options_init(wrapper->wrapped);

  return TypedData_Wrap_Struct(cls, &grpc_rb_compression_options_data_type,
                               wrapper);
}

/* Disables a compression algorithm, given the GRPC core internal number of a
 * compression algorithm. */
VALUE grpc_rb_compression_options_disable_compression_algorithm_internal(
    VALUE self, VALUE algorithm_to_disable) {
  grpc_compression_algorithm compression_algorithm = 0;
  grpc_rb_compression_options* wrapper = NULL;

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);
  compression_algorithm =
      (grpc_compression_algorithm)NUM2INT(algorithm_to_disable);

  grpc_compression_options_disable_algorithm(wrapper->wrapped,
                                             compression_algorithm);

  return Qnil;
}

/* Gets the compression internal enum value of a compression level given its
 * name. */
grpc_compression_level grpc_rb_compression_options_level_name_to_value_internal(
    VALUE level_name) {
  Check_Type(level_name, T_SYMBOL);

  /* Check the compression level of the name passed in, and see which macro
   * from the GRPC core header files match. */
  if (id_compress_level_none == SYM2ID(level_name)) {
    return GRPC_COMPRESS_LEVEL_NONE;
  } else if (id_compress_level_low == SYM2ID(level_name)) {
    return GRPC_COMPRESS_LEVEL_LOW;
  } else if (id_compress_level_medium == SYM2ID(level_name)) {
    return GRPC_COMPRESS_LEVEL_MED;
  } else if (id_compress_level_high == SYM2ID(level_name)) {
    return GRPC_COMPRESS_LEVEL_HIGH;
  }

  rb_raise(rb_eArgError,
           "Unrecognized compression level name."
           "Valid compression level names are none, low, medium, and high.");

  /* Dummy return statement. */
  return GRPC_COMPRESS_LEVEL_NONE;
}

/* Sets the default compression level, given the name of a compression level.
 * Throws an error if no algorithm matched. */
void grpc_rb_compression_options_set_default_level(
    grpc_compression_options* options, VALUE new_level_name) {
  options->default_level.level =
      grpc_rb_compression_options_level_name_to_value_internal(new_level_name);
  options->default_level.is_set = 1;
}

/* Gets the internal value of a compression algorithm suitable as the value
 * in a GRPC core channel arguments hash.
 * algorithm_value is an out parameter.
 * Raises an error if the name of the algorithm passed in is invalid. */
void grpc_rb_compression_options_algorithm_name_to_value_internal(
    grpc_compression_algorithm* algorithm_value, VALUE algorithm_name) {
  grpc_slice name_slice;
  VALUE algorithm_name_as_string = Qnil;

  Check_Type(algorithm_name, T_SYMBOL);

  /* Convert the algorithm symbol to a ruby string, so that we can get the
   * correct C string out of it. */
  algorithm_name_as_string = rb_funcall(algorithm_name, rb_intern("to_s"), 0);

  name_slice =
      grpc_slice_from_copied_buffer(RSTRING_PTR(algorithm_name_as_string),
                                    RSTRING_LEN(algorithm_name_as_string));

  /* Raise an error if the name isn't recognized as a compression algorithm by
   * the algorithm parse function
   * in GRPC core. */
  if (!grpc_compression_algorithm_parse(name_slice, algorithm_value)) {
    char* name_slice_str = grpc_slice_to_c_string(name_slice);
    char* error_message_str = NULL;
    VALUE error_message_ruby_str = Qnil;
    GPR_ASSERT(gpr_asprintf(&error_message_str,
                            "Invalid compression algorithm name: %s",
                            name_slice_str) != -1);
    gpr_free(name_slice_str);
    error_message_ruby_str =
        rb_str_new(error_message_str, strlen(error_message_str));
    gpr_free(error_message_str);
    rb_raise(rb_eNameError, "%s", StringValueCStr(error_message_ruby_str));
  }

  grpc_slice_unref(name_slice);
}

/* Indicates whether a given algorithm is enabled on this instance, given the
 * readable algorithm name. */
VALUE grpc_rb_compression_options_is_algorithm_enabled(VALUE self,
                                                       VALUE algorithm_name) {
  grpc_rb_compression_options* wrapper = NULL;
  grpc_compression_algorithm internal_algorithm_value;

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);
  grpc_rb_compression_options_algorithm_name_to_value_internal(
      &internal_algorithm_value, algorithm_name);

  if (grpc_compression_options_is_algorithm_enabled(wrapper->wrapped,
                                                    internal_algorithm_value)) {
    return Qtrue;
  }
  return Qfalse;
}

/* Sets the default algorithm to the name of the algorithm passed in.
 * Raises an error if the name is not a valid compression algorithm name. */
void grpc_rb_compression_options_set_default_algorithm(
    grpc_compression_options* options, VALUE algorithm_name) {
  grpc_rb_compression_options_algorithm_name_to_value_internal(
      &options->default_algorithm.algorithm, algorithm_name);
  options->default_algorithm.is_set = 1;
}

/* Disables an algorithm on the current instance, given the name of an
 * algorithm.
 * Fails if the algorithm name is invalid. */
void grpc_rb_compression_options_disable_algorithm(
    grpc_compression_options* compression_options, VALUE algorithm_name) {
  grpc_compression_algorithm internal_algorithm_value;

  grpc_rb_compression_options_algorithm_name_to_value_internal(
      &internal_algorithm_value, algorithm_name);
  grpc_compression_options_disable_algorithm(compression_options,
                                             internal_algorithm_value);
}

/* Provides a ruby hash of GRPC core channel argument key-values that
 * correspond to the compression settings on this instance. */
VALUE grpc_rb_compression_options_to_hash(VALUE self) {
  grpc_rb_compression_options* wrapper = NULL;
  grpc_compression_options* compression_options = NULL;
  VALUE channel_arg_hash = rb_hash_new();
  VALUE key = Qnil;
  VALUE value = Qnil;

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);
  compression_options = wrapper->wrapped;

  /* Add key-value pairs to the new Ruby hash. It can be used
   * as GRPC core channel arguments. */
  if (compression_options->default_level.is_set) {
    key = rb_str_new2(GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL);
    value = INT2NUM((int)compression_options->default_level.level);
    rb_hash_aset(channel_arg_hash, key, value);
  }

  if (compression_options->default_algorithm.is_set) {
    key = rb_str_new2(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM);
    value = INT2NUM((int)compression_options->default_algorithm.algorithm);
    rb_hash_aset(channel_arg_hash, key, value);
  }

  key = rb_str_new2(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET);
  value = INT2NUM((int)compression_options->enabled_algorithms_bitset);
  rb_hash_aset(channel_arg_hash, key, value);

  return channel_arg_hash;
}

/* Converts an internal enum level value to a readable level name.
 * Fails if the level value is invalid. */
VALUE grpc_rb_compression_options_level_value_to_name_internal(
    grpc_compression_level compression_value) {
  switch (compression_value) {
    case GRPC_COMPRESS_LEVEL_NONE:
      return ID2SYM(id_compress_level_none);
    case GRPC_COMPRESS_LEVEL_LOW:
      return ID2SYM(id_compress_level_low);
    case GRPC_COMPRESS_LEVEL_MED:
      return ID2SYM(id_compress_level_medium);
    case GRPC_COMPRESS_LEVEL_HIGH:
      return ID2SYM(id_compress_level_high);
    default:
      rb_raise(
          rb_eArgError,
          "Failed to convert compression level value to name for value: %d",
          (int)compression_value);
      /* return something to avoid compiler error about no return */
      return Qnil;
  }
}

/* Converts an algorithm internal enum value to a readable name.
 * Fails if the enum value is invalid. */
VALUE grpc_rb_compression_options_algorithm_value_to_name_internal(
    grpc_compression_algorithm internal_value) {
  char* algorithm_name = NULL;

  if (!grpc_compression_algorithm_name(internal_value, &algorithm_name)) {
    rb_raise(rb_eArgError, "Failed to convert algorithm value to name");
  }

  return ID2SYM(rb_intern(algorithm_name));
}

/* Gets the readable name of the default algorithm if one has been set.
 * Returns nil if no algorithm has been set. */
VALUE grpc_rb_compression_options_get_default_algorithm(VALUE self) {
  grpc_compression_algorithm internal_value;
  grpc_rb_compression_options* wrapper = NULL;

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);

  if (wrapper->wrapped->default_algorithm.is_set) {
    internal_value = wrapper->wrapped->default_algorithm.algorithm;
    return grpc_rb_compression_options_algorithm_value_to_name_internal(
        internal_value);
  }

  return Qnil;
}

/* Gets the internal value of the default compression level that is to be passed
 * to the GRPC core as a channel argument value.
 * A nil return value means that it hasn't been set. */
VALUE grpc_rb_compression_options_get_default_level(VALUE self) {
  grpc_compression_level internal_value;
  grpc_rb_compression_options* wrapper = NULL;

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);

  if (wrapper->wrapped->default_level.is_set) {
    internal_value = wrapper->wrapped->default_level.level;
    return grpc_rb_compression_options_level_value_to_name_internal(
        internal_value);
  }

  return Qnil;
}

/* Gets a list of the disabled algorithms as readable names.
 * Returns an empty list if no algorithms have been disabled. */
VALUE grpc_rb_compression_options_get_disabled_algorithms(VALUE self) {
  VALUE disabled_algorithms = rb_ary_new();
  grpc_compression_algorithm internal_value;
  grpc_rb_compression_options* wrapper = NULL;

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);

  for (internal_value = GRPC_COMPRESS_NONE;
       internal_value < GRPC_COMPRESS_ALGORITHMS_COUNT; internal_value++) {
    if (!grpc_compression_options_is_algorithm_enabled(wrapper->wrapped,
                                                       internal_value)) {
      rb_ary_push(disabled_algorithms,
                  grpc_rb_compression_options_algorithm_value_to_name_internal(
                      internal_value));
    }
  }
  return disabled_algorithms;
}

/* Initializes the compression options wrapper.
 * Takes an optional hash parameter.
 *
 * Example call-seq:
 *   options = CompressionOptions.new(
 *     default_level: :none,
 *     disabled_algorithms: [:gzip]
 *   )
 *   channel_arg hash = Hash.new[...]
 *   channel_arg_hash_with_compression_options = channel_arg_hash.merge(options)
 */
VALUE grpc_rb_compression_options_init(int argc, VALUE* argv, VALUE self) {
  grpc_rb_compression_options* wrapper = NULL;
  VALUE default_algorithm = Qnil;
  VALUE default_level = Qnil;
  VALUE disabled_algorithms = Qnil;
  VALUE algorithm_name = Qnil;
  VALUE hash_arg = Qnil;

  rb_scan_args(argc, argv, "01", &hash_arg);

  /* Check if the hash parameter was passed, or if invalid arguments were
   * passed. */
  if (hash_arg == Qnil) {
    return self;
  } else if (TYPE(hash_arg) != T_HASH || argc > 1) {
    rb_raise(rb_eArgError,
             "Invalid arguments. Expecting optional hash parameter");
  }

  TypedData_Get_Struct(self, grpc_rb_compression_options,
                       &grpc_rb_compression_options_data_type, wrapper);

  /* Set the default algorithm if one was chosen. */
  default_algorithm =
      rb_hash_aref(hash_arg, ID2SYM(rb_intern("default_algorithm")));
  if (default_algorithm != Qnil) {
    grpc_rb_compression_options_set_default_algorithm(wrapper->wrapped,
                                                      default_algorithm);
  }

  /* Set the default level if one was chosen. */
  default_level = rb_hash_aref(hash_arg, ID2SYM(rb_intern("default_level")));
  if (default_level != Qnil) {
    grpc_rb_compression_options_set_default_level(wrapper->wrapped,
                                                  default_level);
  }

  /* Set the disabled algorithms if any were chosen. */
  disabled_algorithms =
      rb_hash_aref(hash_arg, ID2SYM(rb_intern("disabled_algorithms")));
  if (disabled_algorithms != Qnil) {
    Check_Type(disabled_algorithms, T_ARRAY);

    for (int i = 0; i < RARRAY_LEN(disabled_algorithms); i++) {
      algorithm_name = rb_ary_entry(disabled_algorithms, i);
      grpc_rb_compression_options_disable_algorithm(wrapper->wrapped,
                                                    algorithm_name);
    }
  }

  return self;
}

void Init_grpc_compression_options() {
  grpc_rb_cCompressionOptions = rb_define_class_under(
      grpc_rb_mGrpcCore, "CompressionOptions", rb_cObject);

  /* Allocates an object managed by the ruby runtime. */
  rb_define_alloc_func(grpc_rb_cCompressionOptions,
                       grpc_rb_compression_options_alloc);

  /* Initializes the ruby wrapper. #new method takes an optional hash argument.
   */
  rb_define_method(grpc_rb_cCompressionOptions, "initialize",
                   grpc_rb_compression_options_init, -1);

  /* Methods for getting the default algorithm, default level, and disabled
   * algorithms as readable names. */
  rb_define_method(grpc_rb_cCompressionOptions, "default_algorithm",
                   grpc_rb_compression_options_get_default_algorithm, 0);
  rb_define_method(grpc_rb_cCompressionOptions, "default_level",
                   grpc_rb_compression_options_get_default_level, 0);
  rb_define_method(grpc_rb_cCompressionOptions, "disabled_algorithms",
                   grpc_rb_compression_options_get_disabled_algorithms, 0);

  /* Determines whether or not an algorithm is enabled, given a readable
   * algorithm name.*/
  rb_define_method(grpc_rb_cCompressionOptions, "algorithm_enabled?",
                   grpc_rb_compression_options_is_algorithm_enabled, 1);

  /* Provides a hash of the compression settings suitable
   * for passing to server or channel args. */
  rb_define_method(grpc_rb_cCompressionOptions, "to_hash",
                   grpc_rb_compression_options_to_hash, 0);
  rb_define_alias(grpc_rb_cCompressionOptions, "to_channel_arg_hash",
                  "to_hash");

  /* Ruby ids for the names of the different compression levels. */
  id_compress_level_none = rb_intern("none");
  id_compress_level_low = rb_intern("low");
  id_compress_level_medium = rb_intern("medium");
  id_compress_level_high = rb_intern("high");
}
