/*****************************************************************************
 *                                  _   _ ____  _     
 *  Project                     ___| | | |  _ \| |    
 *                             / __| | | | |_) | |    
 *                            | (__| |_| |  _ <| |___ 
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * In order to be useful for every potential user, curl and libcurl are
 * dual-licensed under the MPL and the MIT/X-derivate licenses.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the MPL or the MIT/X-derivate
 * licenses. You may pick one of these licenses.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id$
 *****************************************************************************/

#include <curl/curl.h> /* libcurl header */
#include "CurlGlue.h"  /* the JNI-generated glue header file */

/*
 * This is a private struct allocated for every 'CurlGlue' object.
 */
struct javacurl {
  void *libcurl;
  void *whatever;
  struct writecallback {
    jmethodID mid;
    JNIEnv *java;
    jclass cls; /* global reference */
    jobject object;
  } write;
};

JNIEXPORT jint JNICALL Java_CurlGlue_jni_1init(JNIEnv *java,
                                               jobject myself)
{
  void *libhandle;
  struct javacurl *jcurl=NULL;

  libhandle = curl_easy_init();

  if(libhandle) {
    jcurl=(struct javacurl *)malloc(sizeof(struct javacurl));
    if(jcurl) {
      memset(jcurl, 0, sizeof(struct javacurl));
      jcurl->libcurl = libhandle;

    }
    else {
      curl_easy_cleanup(libhandle);
      return (jint)0;
    }
  }

  return (jint) jcurl; /* nasty typecast */
}

JNIEXPORT void JNICALL Java_CurlGlue_jni_1cleanup(JNIEnv *java,
                                                  jobject myself,
                                                  jint jcurl)
{

  struct javacurl *curl = (struct javacurl*)jcurl;

  if(curl->write.cls) {
    /* a global reference we must delete */
    (*java)->DeleteGlobalRef(java, curl->write.cls);
    (*java)->DeleteGlobalRef(java, curl->write.object);
  }

  curl_easy_cleanup(curl->libcurl); /* cleanup libcurl stuff */

  free((void *)curl); /* free the struct too */
}

/*
 * setopt() int + string
 */
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILjava_lang_String_2
  (JNIEnv *java, jobject myself, jint jcurl, jint option, jstring value)
{
  /* get the actual string C-style */
  const char *str = (*java)->GetStringUTFChars(java, value, 0);

  void *handle = (void *)((struct javacurl*)jcurl)->libcurl;

  puts("setopt int + string");
  
  return (jint)curl_easy_setopt(handle, (CURLoption)option, str);

}

/*
 * setopt() int + int 
 */
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__III
  (JNIEnv *java, jobject myself, jint jcurl, jint option, jint value)
{
  void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
  CURLoption opt = (CURLoption)option;

  puts("setopt int + int");

  switch(opt) {
  case CURLOPT_FILE:
    /* silently ignored, we don't need user-specified callback data when
       we have an object, and besides the CURLOPT_FILE is not exported
       to the java interface */
    return 0;
  }

  return (jint)curl_easy_setopt(handle, (CURLoption)option, value);
}

static int javacurl_write_callback(void *ptr,
                                   size_t size,
                                   size_t nmemb,
                                   FILE  *stream)
{
  struct javacurl *curl = (struct javacurl *)stream;
  size_t realsize = size * nmemb;
  JNIEnv *java = curl->write.java;
  jbyteArray jb=NULL;
  int ret=0;

  fprintf(stderr, "%d bytes data received in callback:\n"
          "ptr=%p, java=%p cls=%p\n",
          realsize, curl, java, curl->write.cls);

  jb=(*java)->NewByteArray(java, realsize);
  (*java)->SetByteArrayRegion(java, jb, 0, 
                              realsize, (jbyte *)ptr);

  fprintf(stderr, "created byte-array\n");

  ret = (*java)->CallIntMethod(java,
                               curl->write.object,
                               curl->write.mid,
                               jb);

  fprintf(stderr, "java-method returned %d\n", ret);

  return realsize;
}

/*
 * setopt() int + object
 */

JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILCurlWrite_2
  (JNIEnv *java, jobject myself, jint jcurl, jint option, jobject object)
{
  jclass cls_local = (*java)->GetObjectClass(java, object);
  jmethodID mid;
  struct javacurl *curl = (struct javacurl *)jcurl;
  jclass cls;
  jobject obj_global;

  switch(option) {
  case CURLOPT_WRITEFUNCTION:
    /* this makes a reference that'll be alive until we kill it! */
    cls = (*java)->NewGlobalRef(java, cls_local);

    printf("setopt int + object, option = %d cls= %p\n",
           option, cls);

    if(!cls) {
      puts("couldn't make local reference global");
      return 0;
    }

    /* this is the write callback */
    mid = (*java)->GetMethodID(java, cls, "handleString", "([B)I");
    if(!mid) {
      puts("no callback method found");
      return 0;
    }

    obj_global = (*java)->NewGlobalRef(java, object);

    curl->write.mid = mid;
    curl->write.cls = cls;
    curl->write.object = obj_global;
    /*curl->write.java = java; stored on perform */

    fprintf(stderr, "setopt write callback and write file pointer %p, java = %p\n",
            curl, java);

    curl_easy_setopt(curl->libcurl, CURLOPT_WRITEFUNCTION,
                     javacurl_write_callback);
    curl_easy_setopt(curl->libcurl, CURLOPT_FILE,
                     curl);

    break;
  }
  return 0;
}

JNIEXPORT jint JNICALL Java_CurlGlue_getinfo
  (JNIEnv *java, jobject value)
{
    return 0;
}

JNIEXPORT jint JNICALL Java_CurlGlue_jni_1perform
  (JNIEnv *java, jobject myself, jint jcurl)
{
  struct javacurl *curl=(struct javacurl*)jcurl;
  curl->write.java = java;
  return (jint)curl_easy_perform(curl->libcurl);
}
