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

#include <string.h>

#include "rb_byte_buffer.h"
#include "rb_grpc.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>

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.");

  /* Phony 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");
}
