/*
 * wsman-filter.i
 *
 * filter declarations for openwsman swig bindings
 *
 */

 
%rename(Filter) filter_t;
%nodefault filter_t;
typedef struct {
    char *resultClass;
    char *assocClass;
} filter_t;

#if defined(SWIGRUBY)
%{
  /*
   * Build associators (type == 0) or references (type == 1) filter
   *
   */
  static int associators_references( void *filter, int type, VALUE epr_v, VALUE assocClass_v, VALUE resultClass_v, VALUE role_v, VALUE resultRole_v, VALUE resultProp_v, VALUE propNum_v)
  {
    epr_t *epr = NULL;
    const char *assocClass = as_string(assocClass_v);
    const char *resultClass = as_string(resultClass_v);
    const char *role = as_string(role_v);
    const char *resultRole = as_string(resultRole_v);
    char **resultProp = NULL;
    int propNum = 0;
    int res;
    KLASS_DECL(SwigClassEndPointReference,SWIGTYPE_p_epr_t);

    if (CLASS_OF(epr_v) == KLASS_OF(SwigClassEndPointReference)) {
      SWIG_ConvertPtr(epr_v, (void **)&epr, SWIGTYPE_p_epr_t, 0);
    }
    else {
      epr = epr_from_string(as_string(epr_v));
    }
    if (!NIL_P(resultProp_v)) {
      int i;
      if (TYPE(resultProp_v) != T_ARRAY) {
        SWIG_exception( SWIG_ArgError(resultProp_v), Ruby_Format_TypeError( "", "Array", "resultProp", 6, resultProp_v ) );
      }
      resultProp = (char **)calloc(RARRAY_LEN(resultProp_v), sizeof(char *));
      for (i = 0; i < RARRAY_LEN(resultProp_v); ++i) {
        resultProp[i] = (char *)as_string(rb_ary_entry(resultProp_v, i));
        ++propNum;
      }
    }
    res = filter_set_assoc((filter_t *)filter, epr, type, assocClass, resultClass, role, resultRole, resultProp, propNum);
    if (resultProp) free(resultProp);
    return res;
  }
%}
#endif

/*
 * Filter are evaluated on the server side and help to reduce the amount
 * of processing and information transport.
 *
 * There are five basic ways to filter
 * * associations
 * * references
 * * XPath
 * * CQL (CIM query language)
 * * WQL (WS-Management query language)
 *
 * Openwsman does not do any filter processing by itself but passes it
 * to the backend CIMOM. Support for filters and query languages thus
 * depends on the used CIMOM.
 *
 */
%extend filter_t {
  /*
   * Create empty filter
   *
   */
  filter_t() {
    return filter_initialize();
  }
  ~filter_t() {
    filter_destroy( $self );
  }
#if defined(SWIGJAVA)
  %typemap(in) (char **resultProp, const int propNum) {
	  int i = 0;
	  $2 = (*jenv)->GetArrayLength(jenv, $input);
	  $1 = (char **) malloc(($2+1)*sizeof(char *));
	  /* make a copy of each string */
	  for (i = 0; i<$2; i++) {
		  jstring j_string = (jstring)(*jenv)->GetObjectArrayElement(jenv, $input, i);
		  const char * c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0);
		  $1[i] = malloc((strlen(c_string)+1)*sizeof(char));
		  strcpy($1[i], c_string);
		  (*jenv)->ReleaseStringUTFChars(jenv, j_string, c_string);
		  (*jenv)->DeleteLocalRef(jenv, j_string);
	  }
	  $1[i] = 0;
  }
/* This cleans up the memory we malloc'd before the function call */
  %typemap(freearg) (char **resultProp, const int propNum) {
	  int i;
	  for (i=0; i<$2-1; i++)
		  free($1[i]);
	  free($1);
  }
  %typemap(jni) (char **resultProp, const int propNum) "jobjectArray"
  %typemap(jtype) (char **resultProp, const int propNum) "String[]"
  %typemap(jstype) (char **resultProp, const int propNum) "String[]"
  %typemap(javain) (char **resultProp, const int propNum) "$javainput"
#endif
#if defined(SWIGRUBY)
  /*
   * Set associators filter
   * call-seq:
   *   filter.associators(end_point_reference, assoc_class_name, result_class_name, role, result_role, result_prop[], prop_num)
   *
   */
  int associators( VALUE epr_v = Qnil, VALUE assocClass_v = Qnil, VALUE resultClass_v = Qnil, VALUE role_v = Qnil, VALUE resultRole_v = Qnil, VALUE resultProp_v = Qnil, VALUE propNum_v = Qnil)
  {
    return associators_references( $self, 0, epr_v, assocClass_v, resultClass_v, role_v, resultRole_v, resultProp_v, propNum_v);
  }
#else
  int associators( epr_t *epr, const char *assocClass, const char *resultClass,
        const char *role, const char *resultRole, char **resultProp, const int propNum)
  {
    return filter_set_assoc($self, epr, 0, assocClass, resultClass, role, resultRole, resultProp, propNum);
  }
#endif
#if defined(SWIGRUBY)
  /*
   * Set references filter
   *
   * call-seq:
   *   filter.references(end_point_reference, assoc_class_name, result_class_name, role, result_role, result_prop[], prop_num)
   *
   */
  int references( VALUE epr_v = Qnil, VALUE assocClass_v = Qnil, VALUE resultClass_v = Qnil, VALUE role_v = Qnil, VALUE resultRole_v = Qnil, VALUE resultProp_v = Qnil, VALUE propNum_v = Qnil)
  {
    return associators_references( $self, 1, epr_v, assocClass_v, resultClass_v, role_v, resultRole_v, resultProp_v, propNum_v);
  }
#else
  int references( epr_t *epr, const char *assocClass,
    const char *resultClass, const char *role, const char *resultRole, char **resultProp, const int propNum)
  {
    return filter_set_assoc($self, epr, 1, assocClass, resultClass, role, resultRole, resultProp, propNum);
  }
#endif

  /*
   * Set simple dialect/query filter
   * call-seq:
   *   filter.simple(dialect, query)
   *
   */
  int simple(const char *dialect, const char *query) {
    return filter_set_simple($self, dialect, query );
  }
  /*
   * Set XPath filter
   * call-seq:
   *   filter.xpath(query)
   *
   */
  int xpath(const char *query) {
    return filter_set_simple($self, WSM_XPATH_FILTER_DIALECT, query );
  }
  /*
   * Set CQL (CIM query language) filter
   * call-seq:
   *   filter.cql(query)
   *
   */
  int cql(const char *query) {
    return filter_set_simple($self, WSM_CQL_FILTER_DIALECT, query );
  }
  /*
   * Set WQL (WS-Management query language) filter
   * call-seq:
   *   filter.wql(query)
   *
   */
  int wql(const char *query) {
    return filter_set_simple($self, WSM_WQL_FILTER_DIALECT, query );
  }

}
