/* call-seq:
 * conn.get_option(opt)  => String
 *
 * Return the value associated with the option, +opt+.
 */
VALUE
rb_ldap_conn_get_option (VALUE self, VALUE opt)
{
#ifdef HAVE_LDAP_GET_OPTION
  RB_LDAP_DATA *ldapdata;
  static RB_LDAP_DATA dummy = { NULL, 0, 0 };
  long *data;
  int copt;
  VALUE val;

  if (NIL_P (self))
    {
      if (dummy.ldap == NULL)
        dummy.ldap = ldap_init ("", 0);
      ldapdata = &dummy;
    }
  else
    GET_LDAP_DATA (self, ldapdata);
  copt = NUM2INT (opt);

#if defined(LDAP_OPT_API_INFO) && defined(LDAP_API_INFO_VERSION)
  if (copt == LDAP_OPT_API_INFO)
    {
      LDAPAPIInfo *info;

      info = ALLOCA_N (LDAPAPIInfo, 1);
      /* This is from the Netscape SDK docs for 4.1* */
      info->ldapai_info_version = LDAP_API_INFO_VERSION;
      ldapdata->err = ldap_get_option (NULL, copt, (void *) info);
      data = (long *) info;
    }
  else
    {
      data = (void *) ALLOCA_N (char, LDAP_GET_OPT_MAX_BUFFER_SIZE);
      ldapdata->err = ldap_get_option (ldapdata->ldap, copt, (void *) data);
    }
#else
  data = (void *) ALLOCA_N (char, LDAP_GET_OPT_MAX_BUFFER_SIZE);
  ldapdata->err = ldap_get_option (ldapdata->ldap, copt, (void *) data);
#endif

  if (ldapdata->err == LDAP_OPT_SUCCESS)
    {
      switch (copt)
        {
        case LDAP_OPT_DEREF:
        case LDAP_OPT_SIZELIMIT:
        case LDAP_OPT_TIMELIMIT:
        case LDAP_OPT_REFERRALS:
        case LDAP_OPT_RESTART:
        case LDAP_OPT_PROTOCOL_VERSION:
        case LDAP_OPT_ERROR_NUMBER:
#ifdef USE_OPENLDAP2
#ifdef LDAP_OPT_X_TLS
        case LDAP_OPT_X_TLS:
#endif
#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
#endif
#endif
          val = INT2NUM ((int) (*data));
          break;

        case LDAP_OPT_HOST_NAME:
        case LDAP_OPT_ERROR_STRING:
#ifdef LDAP_OPT_MATCHED_DN
        case LDAP_OPT_MATCHED_DN:
#endif
#ifdef USE_OPENLDAP2
#ifdef LDAP_OPT_X_TLS_CACERTFILE
        case LDAP_OPT_X_TLS_CACERTFILE:
#endif
#ifdef LDAP_OPT_X_TLS_CACERTDIR
        case LDAP_OPT_X_TLS_CACERTDIR:
#endif
#ifdef LDAP_OPT_X_TLS_CERT
        case LDAP_OPT_X_TLS_CERT:
#endif
#ifdef LDAP_OPT_X_TLS_CERTFILE
        case LDAP_OPT_X_TLS_CERTFILE:
#endif
#ifdef LDAP_OPT_X_TLS_KEYFILE
        case LDAP_OPT_X_TLS_KEYFILE:
#endif
#ifdef LDAP_OPT_X_TLS_PROTOCOL
        case LDAP_OPT_X_TLS_PROTOCOL:
#endif
#ifdef LDAP_OPT_X_TLS_CIPHER_SUITE
        case LDAP_OPT_X_TLS_CIPHER_SUITE:
#endif
#ifdef LDAP_OPT_X_TLS_RANDOM_FILE
        case LDAP_OPT_X_TLS_RANDOM_FILE:
#endif
#endif
          val = (data
                 && *data) ? rb_tainted_str_new2 ((char *) (*data)) : Qnil;
          break;
#ifdef LDAP_OPT_API_INFO
        case LDAP_OPT_API_INFO:
          val = rb_ldap_apiinfo_new ((LDAPAPIInfo *) data);
          break;
#endif
        default:
          rb_notimplement ();
        };

      return val;
    }
  else
    {
      rb_raise (rb_eLDAP_Error, ldap_err2string (ldapdata->err));
    };
#else
  rb_notimplement ();
#endif
}