/*
 * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jlong.h"
#include "sun_net_spi_DefaultProxySelector.h"
#include <dlfcn.h>
#include <stdio.h>
#ifdef __linux__
#include <string.h>
#else
#include <strings.h>
#endif

/**
 * These functions are used by the sun.net.spi.DefaultProxySelector class
 * to access some platform specific settings.
 * This is the Solaris/Linux Gnome 2.x code using the GConf-2 library.
 * Everything is loaded dynamically so no hard link with any library exists.
 * The GConf-2 settings used are:
 * - /system/http_proxy/use_http_proxy          boolean
 * - /system/http_proxy/use_authentcation       boolean
 * - /system/http_proxy/host                    string
 * - /system/http_proxy/authentication_user     string
 * - /system/http_proxy/authentication_password string
 * - /system/http_proxy/port                    int
 * - /system/proxy/socks_host                   string
 * - /system/proxy/mode                         string
 * - /system/proxy/ftp_host                     string
 * - /system/proxy/secure_host                  string
 * - /system/proxy/socks_port                   int
 * - /system/proxy/ftp_port                     int
 * - /system/proxy/secure_port                  int
 * - /system/proxy/no_proxy_for                 list
 * - /system/proxy/gopher_host                  string
 * - /system/proxy/gopher_port                  int
 */
typedef void* gconf_client_get_default_func();
typedef char* gconf_client_get_string_func(void *, char *, void**);
typedef int   gconf_client_get_int_func(void*, char *, void**);
typedef int   gconf_client_get_bool_func(void*, char *, void**);
typedef int   gconf_init_func(int, char**, void**);
typedef void  g_type_init_func ();
gconf_client_get_default_func* my_get_default_func = NULL;
gconf_client_get_string_func* my_get_string_func = NULL;
gconf_client_get_int_func* my_get_int_func = NULL;
gconf_client_get_bool_func* my_get_bool_func = NULL;
gconf_init_func* my_gconf_init_func = NULL;
g_type_init_func* my_g_type_init_func = NULL;

static jclass proxy_class;
static jclass isaddr_class;
static jclass ptype_class;
static jmethodID isaddr_createUnresolvedID;
static jmethodID proxy_ctrID;
static jfieldID pr_no_proxyID;
static jfieldID ptype_httpID;
static jfieldID ptype_socksID;

static int gconf_ver = 0;
static void* gconf_client = NULL;

#define CHECK_NULL(X) { if ((X) == NULL) fprintf (stderr,"JNI errror at line %d\n", __LINE__); }

/*
 * Class:     sun_net_spi_DefaultProxySelector
 * Method:    init
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL
Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
  jclass cls = NULL;
  CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy"));
  proxy_class = (*env)->NewGlobalRef(env, cls);
  CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy$Type"));
  ptype_class = (*env)->NewGlobalRef(env, cls);
  CHECK_NULL(cls = (*env)->FindClass(env, "java/net/InetSocketAddress"));
  isaddr_class = (*env)->NewGlobalRef(env, cls);
  proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>", "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
  pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");
  ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");
  ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");
  isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved", "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");

  /**
   * Let's try to load le GConf-2 library
   */
  if (dlopen("libgconf-2.so", RTLD_GLOBAL | RTLD_LAZY) != NULL ||
      dlopen("libgconf-2.so.4", RTLD_GLOBAL | RTLD_LAZY) != NULL) {
    gconf_ver = 2;
  }
  if (gconf_ver > 0) {
    /*
     * Now let's get pointer to the functions we need.
     */
    my_g_type_init_func = (g_type_init_func*) dlsym(RTLD_DEFAULT, "g_type_init");
    my_get_default_func = (gconf_client_get_default_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_default");
    if (my_g_type_init_func != NULL && my_get_default_func != NULL) {
      /**
       * Try to connect to GConf.
       */
      (*my_g_type_init_func)();
      gconf_client = (*my_get_default_func)();
      if (gconf_client != NULL) {
        my_get_string_func = (gconf_client_get_string_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_string");
        my_get_int_func = (gconf_client_get_int_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_int");
        my_get_bool_func = (gconf_client_get_bool_func*) dlsym(RTLD_DEFAULT, "gconf_client_get_bool");
        if (my_get_int_func != NULL && my_get_string_func != NULL &&
            my_get_bool_func != NULL) {
          /**
           * We did get all we need. Let's enable the System Proxy Settings.
           */
          return JNI_TRUE;
        }
      }
    }
  }
  return JNI_FALSE;
}


/*
 * Class:     sun_net_spi_DefaultProxySelector
 * Method:    getSystemProxy
 * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
 */
JNIEXPORT jobject JNICALL
Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
                                                     jobject this,
                                                     jstring proto,
                                                     jstring host)
{
  char *phost = NULL;
  char *mode = NULL;
  int pport = 0;
  int use_proxy;
  const char* urlhost;
  jobject isa = NULL;
  jobject proxy = NULL;
  jobject type_proxy = NULL;
  jobject no_proxy = NULL;
  const char *cproto;
  jboolean isCopy;

  if (gconf_ver > 0) {
    if (gconf_client == NULL) {
      (*my_g_type_init_func)();
      gconf_client = (*my_get_default_func)();
    }
    if (gconf_client != NULL) {
      cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
      if (cproto != NULL) {
        /**
         * We will have to check protocol by protocol as they do use different
         * entries.
         */

        /**
         * HTTP:
         * /system/http_proxy/use_http_proxy (boolean)
         * /system/http_proxy/host (string)
         * /system/http_proxy/port (integer)
         */
        if (strcasecmp(cproto, "http") == 0) {
          use_proxy = (*my_get_bool_func)(gconf_client, "/system/http_proxy/use_http_proxy", NULL);
          if (use_proxy) {
            phost = (*my_get_string_func)(gconf_client, "/system/http_proxy/host", NULL);
            pport = (*my_get_int_func)(gconf_client, "/system/http_proxy/port", NULL);
            CHECK_NULL(type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID));
          }
        }

        /**
         * HTTPS:
         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
         * /system/proxy/secure_host (string)
         * /system/proxy/secure_port (integer)
         */
        if (strcasecmp(cproto, "https") == 0) {
          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
            phost = (*my_get_string_func)(gconf_client, "/system/proxy/secure_host", NULL);
            pport = (*my_get_int_func)(gconf_client, "/system/proxy/secure_port", NULL);
            use_proxy = (phost != NULL);
            if (use_proxy)
              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
          }
        }

        /**
         * FTP:
         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
         * /system/proxy/ftp_host (string)
         * /system/proxy/ftp_port (integer)
         */
        if (strcasecmp(cproto, "ftp") == 0) {
          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
            phost = (*my_get_string_func)(gconf_client, "/system/proxy/ftp_host", NULL);
            pport = (*my_get_int_func)(gconf_client, "/system/proxy/ftp_port", NULL);
            use_proxy = (phost != NULL);
            if (use_proxy)
              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
          }
        }

        /**
         * GOPHER:
         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
         * /system/proxy/gopher_host (string)
         * /system/proxy/gopher_port (integer)
         */
        if (strcasecmp(cproto, "gopher") == 0) {
          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
            phost = (*my_get_string_func)(gconf_client, "/system/proxy/gopher_host", NULL);
            pport = (*my_get_int_func)(gconf_client, "/system/proxy/gopher_port", NULL);
            use_proxy = (phost != NULL);
            if (use_proxy)
              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
          }
        }

        /**
         * SOCKS:
         * /system/proxy/mode (string) [ "manual" means use proxy settings ]
         * /system/proxy/socks_host (string)
         * /system/proxy/socks_port (integer)
         */
        if (strcasecmp(cproto, "socks") == 0) {
          mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
          if (mode != NULL && (strcasecmp(mode,"manual") == 0)) {
            phost = (*my_get_string_func)(gconf_client, "/system/proxy/socks_host", NULL);
            pport = (*my_get_int_func)(gconf_client, "/system/proxy/socks_port", NULL);
            use_proxy = (phost != NULL);
            if (use_proxy)
              type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
          }
        }

        if (isCopy == JNI_TRUE)
          (*env)->ReleaseStringUTFChars(env, proto, cproto);

        if (use_proxy && (phost != NULL)) {
          jstring jhost;
          char *noproxyfor;
          char *s;

          /**
           * check for the exclude list (aka "No Proxy For" list).
           * It's a list of comma separated suffixes (e.g. domain name).
           */
          noproxyfor = (*my_get_string_func)(gconf_client, "/system/proxy/no_proxy_for", NULL);
          if (noproxyfor != NULL) {
            char *tmpbuf[512];

            s = strtok_r(noproxyfor, ", ", tmpbuf);
            urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
            if (urlhost != NULL) {
              while (s != NULL && strlen(s) <= strlen(urlhost)) {
                if (strcasecmp(urlhost+(strlen(urlhost) - strlen(s)), s) == 0) {
                  /**
                   * the URL host name matches with one of the sufixes,
                   * therefore we have to use a direct connection.
                   */
                  use_proxy = 0;
                  break;
                }
                s = strtok_r(NULL, ", ", tmpbuf);
              }
              if (isCopy == JNI_TRUE)
                (*env)->ReleaseStringUTFChars(env, host, urlhost);
            }
          }
          if (use_proxy) {
            jhost = (*env)->NewStringUTF(env, phost);
            isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
            proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
            return proxy;
          }
        }
      }
    }
  }

  CHECK_NULL(no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID));
  return no_proxy;
}
