/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
%module cproton

%{
#include <proton/engine.h>
#include <proton/message.h>
#include <proton/sasl.h>
#include <proton/messenger.h>
#include <proton/ssl.h>
#include <proton/types.h>
#include <proton/url.h>
#include <proton/reactor.h>
#include <proton/handlers.h>
%}

/*
NOTE: According to ccache-swig man page: "Known problems are using
preprocessor directives within %inline blocks and the use of ’#pragma SWIG’."
This includes using macros in an %inline section.

Keep preprocessor directives and macro expansions in the normal header section.
*/

%include <cstring.i>

%cstring_output_withsize(char *OUTPUT, size_t *OUTPUT_SIZE)
%cstring_output_allocate_size(char **ALLOC_OUTPUT, size_t *ALLOC_SIZE, free(*$1));
%cstring_output_maxsize(char *OUTPUT, size_t MAX_OUTPUT_SIZE)

%{
#if !defined(RSTRING_LEN)
#  define RSTRING_LEN(x) (RSTRING(X)->len)
#  define RSTRING_PTR(x) (RSTRING(x)->ptr)
#endif
%}

%typemap(in) pn_bytes_t {
  if ($input == Qnil) {
    $1.start = NULL;
    $1.size = 0;
  } else {
    $1.start = RSTRING_PTR($input);
    if (!$1.start) {
      $1.size = 0;
    }
    $1.size = RSTRING_LEN($input);
  }
}

%typemap(out) pn_bytes_t {
  $result = rb_str_new($1.start, $1.size);
}

%typemap(in) pn_atom_t
{
  if ($input == Qnil)
    {
      $1.type = PN_NULL;
    }
  else
    {
      switch(TYPE($input))
        {
        case T_TRUE:
          $1.type = PN_BOOL;
          $1.u.as_bool = true;
          break;

        case T_FALSE:
          $1.type = PN_BOOL;
          $1.u.as_bool = false;
          break;

        case T_FLOAT:
          $1.type = PN_FLOAT;
          $1.u.as_float = NUM2DBL($input);
          break;

        case T_STRING:
          $1.type = PN_STRING;
          $1.u.as_bytes.start = RSTRING_PTR($input);
          if ($1.u.as_bytes.start)
            {
              $1.u.as_bytes.size = RSTRING_LEN($input);
            }
          else
            {
              $1.u.as_bytes.size = 0;
            }
          break;

        case T_FIXNUM:
          $1.type = PN_INT;
          $1.u.as_int = FIX2LONG($input);
          break;

        case T_BIGNUM:
          $1.type = PN_LONG;
          $1.u.as_long = NUM2LL($input);
          break;

        }
    }
}

%typemap(out) pn_atom_t
{
  switch($1.type)
    {
    case PN_NULL:
      $result = Qnil;
      break;

    case PN_BOOL:
      $result = $1.u.as_bool ? Qtrue : Qfalse;
      break;

    case PN_BYTE:
      $result = INT2NUM($1.u.as_byte);
      break;

    case PN_UBYTE:
      $result = UINT2NUM($1.u.as_ubyte);
      break;

    case PN_SHORT:
      $result = INT2NUM($1.u.as_short);
      break;

    case PN_USHORT:
      $result = UINT2NUM($1.u.as_ushort);
      break;

    case PN_INT:
      $result = INT2NUM($1.u.as_int);
      break;

     case PN_UINT:
      $result = UINT2NUM($1.u.as_uint);
      break;

    case PN_LONG:
      $result = LL2NUM($1.u.as_long);
      break;

    case PN_ULONG:
      $result = ULL2NUM($1.u.as_ulong);
      break;

    case PN_FLOAT:
      $result = rb_float_new($1.u.as_float);
      break;

    case PN_DOUBLE:
      $result = rb_float_new($1.u.as_double);
      break;

    case PN_STRING:
      $result = rb_str_new($1.u.as_bytes.start, $1.u.as_bytes.size);
      break;

    default:
       break;
    }
}

%typemap (in) pn_decimal32_t
{
  $1 = FIX2UINT($input);
}

%typemap (out) pn_decimal32_t
{
  $result = ULL2NUM($1);
}

%typemap (in) pn_decimal64_t
{
  $1 = NUM2ULL($input);
}

%typemap (out) pn_decimal64_t
{
  $result = ULL2NUM($1);
}

%typemap (in) pn_decimal128_t
{
  int index;

  for(index = 0; index < 16; index++)
    {
      VALUE element = rb_ary_entry($input, index);
      $1.bytes[16 - (index + 1)] = FIX2INT(element);
    }
}

%typemap (out) pn_decimal128_t
{
  int index;

  $result = rb_ary_new2(16);
  for(index = 0; index < 16; index++)
    {
      rb_ary_store($result, 16 - (index + 1), CHR2FIX($1.bytes[index]));
    }
}

%typemap (in) pn_uuid_t
{
  int index;

  for(index = 0; index < 16; index++)
    {
      VALUE element = rb_ary_entry($input, index);
      $1.bytes[16 - (index + 1)] = FIX2INT(element);
    }
}

%typemap (out) pn_uuid_t
{
  int index;

  $result = rb_ary_new2(16);
  for(index = 0; index < 16; index++)
    {
      rb_ary_store($result, 16 - (index + 1), CHR2FIX($1.bytes[index]));
    }
}

int pn_message_encode(pn_message_t *msg, char *OUTPUT, size_t *OUTPUT_SIZE);
%ignore pn_message_encode;

ssize_t pn_link_send(pn_link_t *transport, char *STRING, size_t LENGTH);
%ignore pn_link_send;

%rename(pn_link_recv) wrap_pn_link_recv;
%inline %{
  int wrap_pn_link_recv(pn_link_t *link, char *OUTPUT, size_t *OUTPUT_SIZE) {
    ssize_t sz = pn_link_recv(link, OUTPUT, *OUTPUT_SIZE);
    if (sz >= 0) {
      *OUTPUT_SIZE = sz;
    } else {
      *OUTPUT_SIZE = 0;
    }
    return sz;
  }
%}
%ignore pn_link_recv;

ssize_t pn_transport_input(pn_transport_t *transport, char *STRING, size_t LENGTH);
%ignore pn_transport_input;

%rename(pn_transport_output) wrap_pn_transport_output;
%inline %{
  int wrap_pn_transport_output(pn_transport_t *transport, char *OUTPUT, size_t *OUTPUT_SIZE) {
    ssize_t sz = pn_transport_output(transport, OUTPUT, *OUTPUT_SIZE);
    if (sz >= 0) {
      *OUTPUT_SIZE = sz;
    } else {
      *OUTPUT_SIZE = 0;
    }
    return sz;
  }
%}
%ignore pn_transport_output;

%rename(pn_transport_peek) wrap_pn_transport_peek;
%inline %{
  int wrap_pn_transport_peek(pn_transport_t *transport, char *OUTPUT, size_t *OUTPUT_SIZE) {
    ssize_t sz = pn_transport_peek(transport, OUTPUT, *OUTPUT_SIZE);
    if(sz >= 0) {
      *OUTPUT_SIZE = sz;
    } else {
      *OUTPUT_SIZE = 0;
    }
    return sz;
  }
%}
%ignore pn_transport_peek;

%rename(pn_delivery) wrap_pn_delivery;
%inline %{
  pn_delivery_t *wrap_pn_delivery(pn_link_t *link, char *STRING, size_t LENGTH) {
    return pn_delivery(link, pn_dtag(STRING, LENGTH));
  }
%}
%ignore pn_delivery;

// Suppress "Warning(451): Setting a const char * variable may leak memory." on pn_delivery_tag_t
%warnfilter(451) pn_delivery_tag_t;
%rename(pn_delivery_tag) wrap_pn_delivery_tag;
%inline %{
  void wrap_pn_delivery_tag(pn_delivery_t *delivery, char **ALLOC_OUTPUT, size_t *ALLOC_SIZE) {
    pn_delivery_tag_t tag = pn_delivery_tag(delivery);
    *ALLOC_OUTPUT = malloc(tag.size);
    *ALLOC_SIZE = tag.size;
    memcpy(*ALLOC_OUTPUT, tag.start, tag.size);
  }
%}
%ignore pn_delivery_tag;

bool pn_ssl_get_cipher_name(pn_ssl_t *ssl, char *OUTPUT, size_t MAX_OUTPUT_SIZE);
%ignore pn_ssl_get_cipher_name;

bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *OUTPUT, size_t MAX_OUTPUT_SIZE);
%ignore pn_ssl_get_protocol_name;

%inline %{
#if defined(RUBY20) || defined(RUBY21)

  typedef void *non_blocking_return_t;
#define RB_BLOCKING_CALL rb_thread_call_without_gvl

#elif defined(RUBY19)

    typedef VALUE non_blocking_return_t;
#define RB_BLOCKING_CALL rb_thread_blocking_region

#endif
  %}

%rename(pn_messenger_send) wrap_pn_messenger_send;
%rename(pn_messenger_recv) wrap_pn_messenger_recv;
%rename(pn_messenger_work) wrap_pn_messenger_work;

%inline %{

#if defined(RB_BLOCKING_CALL)

    static non_blocking_return_t pn_messenger_send_no_gvl(void *args) {
    VALUE result = Qnil;
    pn_messenger_t *messenger = (pn_messenger_t *)((void **)args)[0];
    int *limit = (int *)((void **)args)[1];

    int rc = pn_messenger_send(messenger, *limit);

    result = INT2NUM(rc);
    return (non_blocking_return_t )result;
    }

    static non_blocking_return_t pn_messenger_recv_no_gvl(void *args) {
    VALUE result = Qnil;
    pn_messenger_t *messenger = (pn_messenger_t *)((void **)args)[0];
    int *limit = (int *)((void **)args)[1];

    int rc = pn_messenger_recv(messenger, *limit);

    result = INT2NUM(rc);
    return (non_blocking_return_t )result;
  }

    static non_blocking_return_t pn_messenger_work_no_gvl(void *args) {
      VALUE result = Qnil;
      pn_messenger_t *messenger = (pn_messenger_t *)((void **)args)[0];
      int *timeout = (int *)((void **)args)[1];

      int rc = pn_messenger_work(messenger, *timeout);

      result = INT2NUM(rc);
      return (non_blocking_return_t )result;
    }

#endif

  int wrap_pn_messenger_send(pn_messenger_t *messenger, int limit) {
    int result = 0;

#if defined(RB_BLOCKING_CALL)

    // only release the gil if we're blocking
    if(pn_messenger_is_blocking(messenger)) {
      VALUE rc;
      void* args[2];

      args[0] = messenger;
      args[1] = &limit;

      rc = RB_BLOCKING_CALL(pn_messenger_send_no_gvl,
                            &args, RUBY_UBF_PROCESS, NULL);

      if(RTEST(rc))
        {
          result = FIX2INT(rc);
        }
    }

#else // !defined(RB_BLOCKING_CALL)
    result = pn_messenger_send(messenger, limit);
#endif // defined(RB_BLOCKING_CALL)

    return result;
  }

  int wrap_pn_messenger_recv(pn_messenger_t *messenger, int limit) {
    int result = 0;

#if defined(RB_BLOCKING_CALL)
    // only release the gil if we're blocking
    if(pn_messenger_is_blocking(messenger)) {
      VALUE rc;
      void* args[2];

      args[0] = messenger;
      args[1] = &limit;

      rc = RB_BLOCKING_CALL(pn_messenger_recv_no_gvl,
                            &args, RUBY_UBF_PROCESS, NULL);

      if(RTEST(rc))
        {
          result = FIX2INT(rc);
        }

    } else {
      result = pn_messenger_recv(messenger, limit);
    }
#else // !defined(RB_BLOCKING_CALL)
    result = pn_messenger_recv(messenger, limit);
#endif // defined(RB_BLOCKING_CALL)

      return result;
  }

  int wrap_pn_messenger_work(pn_messenger_t *messenger, int timeout) {
    int result = 0;

#if defined(RB_BLOCKING_CALL)
    // only release the gil if we're blocking
    if(timeout) {
      VALUE rc;
      void* args[2];

      args[0] = messenger;
      args[1] = &timeout;

      rc = RB_BLOCKING_CALL(pn_messenger_work_no_gvl,
                            &args, RUBY_UBF_PROCESS, NULL);

      if(RTEST(rc))
        {
          result = FIX2INT(rc);
        }
    } else {
      result = pn_messenger_work(messenger, timeout);
    }
#else
    result = pn_messenger_work(messenger, timeout);
#endif

    return result;
  }

%}

%ignore pn_messenger_send;
%ignore pn_messenger_recv;
%ignore pn_messenger_work;

%{
typedef struct Pn_rbkey_t {
  void *registry;
  char *method;
  char *key_value;
} Pn_rbkey_t;

void Pn_rbkey_initialize(void *vp_rbkey) {
  Pn_rbkey_t *rbkey = (Pn_rbkey_t*)vp_rbkey;
  assert(rbkey);
  rbkey->registry = NULL;
  rbkey->method = NULL;
  rbkey->key_value = NULL;
}

void Pn_rbkey_finalize(void *vp_rbkey) {
  Pn_rbkey_t *rbkey = (Pn_rbkey_t*)vp_rbkey;
  if(rbkey && rbkey->registry && rbkey->method && rbkey->key_value) {
    rb_funcall((VALUE )rbkey->registry, rb_intern(rbkey->method), 1, rb_str_new2(rbkey->key_value));
  }
  if(rbkey->key_value) {
    free(rbkey->key_value);
    rbkey->key_value = NULL;
  }
}

/* NOTE: no macro or preprocessor definitions in %inline sections */
#define CID_Pn_rbkey CID_pn_void
#define Pn_rbkey_inspect NULL
#define Pn_rbkey_compare NULL
#define Pn_rbkey_hashcode NULL

pn_class_t* Pn_rbkey__class(void) {
    static pn_class_t clazz = PN_CLASS(Pn_rbkey);
    return &clazz;
}

Pn_rbkey_t *Pn_rbkey_new(void) {
    return (Pn_rbkey_t *) pn_class_new(Pn_rbkey__class(), sizeof(Pn_rbkey_t));
}
%}

pn_class_t* Pn_rbkey__class(void);
Pn_rbkey_t *Pn_rbkey_new(void);

%inline %{

Pn_rbkey_t *Pn_rbkey_new(void);

void Pn_rbkey_set_registry(Pn_rbkey_t *rbkey, void *registry) {
  assert(rbkey);
  rbkey->registry = registry;
}

void *Pn_rbkey_get_registry(Pn_rbkey_t *rbkey) {
  assert(rbkey);
  return rbkey->registry;
}

void Pn_rbkey_set_method(Pn_rbkey_t *rbkey, char *method) {
  assert(rbkey);
  rbkey->method = method;
}

char *Pn_rbkey_get_method(Pn_rbkey_t *rbkey) {
  assert(rbkey);
  return rbkey->method;
}

void Pn_rbkey_set_key_value(Pn_rbkey_t *rbkey, char *key_value) {
  assert(rbkey);
  rbkey->key_value = malloc(strlen(key_value) + 1);
  strncpy(rbkey->key_value, key_value, strlen(key_value) + 1);
}

char *Pn_rbkey_get_key_value(Pn_rbkey_t *rbkey) {
  assert(rbkey);
  return rbkey->key_value;
}

Pn_rbkey_t *pni_void2rbkey(void *object) {
  return (Pn_rbkey_t *)object;
}

VALUE pn_void2rb(void *object) {
  return (VALUE )object;
}

void *pn_rb2void(VALUE object) {
  return (void *)object;
}

VALUE pni_address_of(void *object) {
  return ULL2NUM((unsigned long )object);
}

%}

//%rename(pn_collector_put) wrap_pn_collector_put;
//%inline %{
//  pn_event_t *wrap_pn_collector_put(pn_collector_t *collector, void *context,
//                               pn_event_type_t type) {
//    return pn_collector_put(collector, PN_RBREF, context, type);
//  }
//  %}
//%ignore pn_collector_put;

int pn_ssl_get_peer_hostname(pn_ssl_t *ssl, char *OUTPUT, size_t *OUTPUT_SIZE);
%ignore pn_ssl_get_peer_hostname;

%inline %{

  VALUE pni_ruby_get_proton_module() {
    VALUE mQpid = rb_define_module("Qpid");
    return rb_define_module_under(mQpid, "Proton");
  }

  void pni_ruby_add_to_registry(VALUE key, VALUE value) {
    VALUE result = rb_funcall(pni_ruby_get_proton_module(), rb_intern("add_to_registry"), 2, key, value);
  }

  VALUE pni_ruby_get_from_registry(VALUE key) {
     return rb_funcall(pni_ruby_get_proton_module(), rb_intern("get_from_registry"), 1, key);
  }

  void pni_ruby_delete_from_registry(VALUE stored_key) {
    rb_funcall(pni_ruby_get_proton_module(), rb_intern("delete_from_registry"), 1, stored_key);
  }

  typedef struct {
    VALUE handler_key;
  } Pni_rbhandler_t;

  static Pni_rbhandler_t *pni_rbhandler(pn_handler_t *handler) {
    return (Pni_rbhandler_t *) pn_handler_mem(handler);
  }

  static void pni_rbdispatch(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type) {
    Pni_rbhandler_t *rbh = pni_rbhandler(handler);
    VALUE rbhandler = pni_ruby_get_from_registry(rbh->handler_key);

    rb_funcall(rbhandler, rb_intern("dispatch"), 2, SWIG_NewPointerObj(event, SWIGTYPE_p_pn_event_t, 0), INT2FIX(type));
  }

  static void pni_rbhandler_finalize(pn_handler_t *handler) {
    Pni_rbhandler_t *rbh = pni_rbhandler(handler);
    pni_ruby_delete_from_registry(rbh->handler_key);
  }

  pn_handler_t *pn_rbhandler(VALUE handler) {
    pn_handler_t *chandler = pn_handler_new(pni_rbdispatch, sizeof(Pni_rbhandler_t), pni_rbhandler_finalize);
    Pni_rbhandler_t *rhy = pni_rbhandler(chandler);

    VALUE ruby_key = rb_class_new_instance(0, NULL, rb_cObject);
    pni_ruby_add_to_registry(ruby_key, handler);

    rhy->handler_key = ruby_key;

    return chandler;
  }

%}

%include "proton/cproton.i"
