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

%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) {
    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"
