/*
 * Copyright 2006, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_TAG "webcoreglue"

#include "config.h"

#include "MemoryCache.h"
#include "Connection.h"
#include "CookieClient.h"
#include "FileSystemClient.h"
#include "JavaSharedClient.h"
#include "KeyGeneratorClient.h"
#include "KURL.h"
#include "NetworkStateNotifier.h"
#include "PackageNotifier.h"
#include "Page.h"
#include "PluginClient.h"
#include "PluginDatabase.h"
#include "Timer.h"
#include "TimerClient.h"
#include "WebCache.h"
#include "WebCoreJni.h"

#include <JNIHelp.h>
#include <JNIUtility.h>
#include <SkUtils.h>
#include <jni.h>
#include <utils/misc.h>
#include <wtf/Platform.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/AtomicString.h>

namespace android {

// ----------------------------------------------------------------------------

static jfieldID gJavaBridge_ObjectID;

// ----------------------------------------------------------------------------
   
class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient, public FileSystemClient
{
public:
    JavaBridge(JNIEnv* env, jobject obj);
    virtual ~JavaBridge();

    /*
     * WebCore -> Java API
     */
    virtual void setSharedTimer(long long timemillis);
    virtual void stopSharedTimer();

    virtual void setCookies(WebCore::KURL const& url, WTF::String const& value);
    virtual WTF::String cookies(WebCore::KURL const& url);
    virtual bool cookiesEnabled();

    virtual WTF::Vector<WTF::String> getPluginDirectories();
    virtual WTF::String getPluginSharedDataDirectory();

    virtual WTF::Vector<String> getSupportedKeyStrengthList();
    virtual WTF::String getSignedPublicKeyAndChallengeString(unsigned index,
            const WTF::String& challenge, const WebCore::KURL& url);
    virtual WTF::String resolveFilePathForContentUri(const WTF::String& uri);

    ////////////////////////////////////////////

    virtual void setSharedTimerCallback(void (*f)());

    ////////////////////////////////////////////

    virtual void signalServiceFuncPtrQueue();

    // jni functions
    static void Constructor(JNIEnv* env, jobject obj);
    static void Finalize(JNIEnv* env, jobject obj);
    static void SharedTimerFired(JNIEnv* env, jobject);
    static void SetCacheSize(JNIEnv* env, jobject obj, jint bytes);
    static void SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online);
    static void SetNetworkType(JNIEnv* env, jobject obj, jstring type, jstring subtype);
    static void SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer);
    static void ServiceFuncPtrQueue(JNIEnv*);
    static void UpdatePluginDirectories(JNIEnv* env, jobject obj, jobjectArray array, jboolean reload);
    static void AddPackageNames(JNIEnv* env, jobject obj, jobject packageNames);
    static void AddPackageName(JNIEnv* env, jobject obj, jstring packageName);
    static void RemovePackageName(JNIEnv* env, jobject obj, jstring packageName);
    static void UpdateProxy(JNIEnv* env, jobject obj, jstring newProxy, jstring newExList);


private:
    jweak       mJavaObject;
    jmethodID   mSetSharedTimer;
    jmethodID   mStopSharedTimer;
    jmethodID   mSetCookies;
    jmethodID   mCookies;
    jmethodID   mCookiesEnabled;
    jmethodID   mGetPluginDirectories;
    jmethodID   mGetPluginSharedDataDirectory;
    jmethodID   mSignalFuncPtrQueue;
    jmethodID   mGetKeyStrengthList;
    jmethodID   mGetSignedPublicKey;
    jmethodID   mResolveFilePathForContentUri;
    AutoJObject javaObject(JNIEnv* env) { return getRealObject(env, mJavaObject); }
};

static void (*sSharedTimerFiredCallback)();

JavaBridge::JavaBridge(JNIEnv* env, jobject obj)
{
    mJavaObject = env->NewWeakGlobalRef(obj);
    jclass clazz = env->GetObjectClass(obj);

    mSetSharedTimer = env->GetMethodID(clazz, "setSharedTimer", "(J)V");
    mStopSharedTimer = env->GetMethodID(clazz, "stopSharedTimer", "()V");
    mSetCookies = env->GetMethodID(clazz, "setCookies", "(Ljava/lang/String;Ljava/lang/String;)V");
    mCookies = env->GetMethodID(clazz, "cookies", "(Ljava/lang/String;)Ljava/lang/String;");
    mCookiesEnabled = env->GetMethodID(clazz, "cookiesEnabled", "()Z");
    mGetPluginDirectories = env->GetMethodID(clazz, "getPluginDirectories", "()[Ljava/lang/String;");
    mGetPluginSharedDataDirectory = env->GetMethodID(clazz, "getPluginSharedDataDirectory", "()Ljava/lang/String;");
    mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V");
    mGetKeyStrengthList = env->GetMethodID(clazz, "getKeyStrengthList", "()[Ljava/lang/String;");
    mGetSignedPublicKey = env->GetMethodID(clazz, "getSignedPublicKey", "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
    mResolveFilePathForContentUri = env->GetMethodID(clazz, "resolveFilePathForContentUri", "(Ljava/lang/String;)Ljava/lang/String;");
    env->DeleteLocalRef(clazz);

    ALOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer");
    ALOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer");
    ALOG_ASSERT(mSetCookies, "Could not find method setCookies");
    ALOG_ASSERT(mCookies, "Could not find method cookies");
    ALOG_ASSERT(mCookiesEnabled, "Could not find method cookiesEnabled");
    ALOG_ASSERT(mGetPluginDirectories, "Could not find method getPluginDirectories");
    ALOG_ASSERT(mGetPluginSharedDataDirectory, "Could not find method getPluginSharedDataDirectory");
    ALOG_ASSERT(mGetKeyStrengthList, "Could not find method getKeyStrengthList");
    ALOG_ASSERT(mGetSignedPublicKey, "Could not find method getSignedPublicKey");

    JavaSharedClient::SetTimerClient(this);
    JavaSharedClient::SetCookieClient(this);
    JavaSharedClient::SetPluginClient(this);
    JavaSharedClient::SetKeyGeneratorClient(this);
    JavaSharedClient::SetFileSystemClient(this);
}

JavaBridge::~JavaBridge()
{
    if (mJavaObject) {
        JNIEnv* env = JSC::Bindings::getJNIEnv();
        env->DeleteWeakGlobalRef(mJavaObject);
        mJavaObject = 0;
    }
    
    JavaSharedClient::SetTimerClient(NULL);
    JavaSharedClient::SetCookieClient(NULL);
    JavaSharedClient::SetPluginClient(NULL);
    JavaSharedClient::SetKeyGeneratorClient(NULL);
    JavaSharedClient::SetFileSystemClient(NULL);
}

void
JavaBridge::setSharedTimer(long long timemillis)
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return;
    env->CallVoidMethod(obj.get(), mSetSharedTimer, timemillis);
}

void
JavaBridge::stopSharedTimer()
{    
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return;
    env->CallVoidMethod(obj.get(), mStopSharedTimer);
}

void
JavaBridge::setCookies(WebCore::KURL const& url, WTF::String const& value)
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return;

    const WTF::String& urlStr = url.string();
    jstring jUrlStr = wtfStringToJstring(env, urlStr);
    jstring jValueStr = wtfStringToJstring(env, value);

    env->CallVoidMethod(obj.get(), mSetCookies, jUrlStr, jValueStr);
    env->DeleteLocalRef(jUrlStr);
    env->DeleteLocalRef(jValueStr);
}

WTF::String
JavaBridge::cookies(WebCore::KURL const& url)
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return String();

    const WTF::String& urlStr = url.string();
    jstring jUrlStr = wtfStringToJstring(env, urlStr);
    jstring string = (jstring)(env->CallObjectMethod(obj.get(), mCookies, jUrlStr));
    
    WTF::String ret = jstringToWtfString(env, string);
    env->DeleteLocalRef(jUrlStr);
    env->DeleteLocalRef(string);
    return ret;
}

bool
JavaBridge::cookiesEnabled()
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return false;
    jboolean ret = env->CallBooleanMethod(obj.get(), mCookiesEnabled);
    return (ret != 0);
}

WTF::Vector<WTF::String>
JavaBridge::getPluginDirectories()
{
    WTF::Vector<WTF::String> directories;
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return directories;
    jobjectArray array = (jobjectArray)
            env->CallObjectMethod(obj.get(), mGetPluginDirectories);
    int count = env->GetArrayLength(array);
    for (int i = 0; i < count; i++) {
        jstring dir = (jstring) env->GetObjectArrayElement(array, i);
        directories.append(jstringToWtfString(env, dir));
        env->DeleteLocalRef(dir);
    }
    env->DeleteLocalRef(array);
    checkException(env);
    return directories;
}

WTF::String
JavaBridge::getPluginSharedDataDirectory()
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return String();
    jstring ret = (jstring)env->CallObjectMethod(obj.get(), mGetPluginSharedDataDirectory);
    WTF::String path = jstringToWtfString(env, ret);
    checkException(env);
    return path;
}

void
JavaBridge::setSharedTimerCallback(void (*f)())
{
    ALOG_ASSERT(!sSharedTimerFiredCallback || sSharedTimerFiredCallback==f,
               "Shared timer callback may already be set or null!");

    sSharedTimerFiredCallback = f;
}
    
void JavaBridge::signalServiceFuncPtrQueue()
{
    // In order to signal the main thread we must go through JNI. This
    // is the only usage on most threads, so we need to ensure a JNI
    // environment is setup.
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return;
    env->CallVoidMethod(obj.get(), mSignalFuncPtrQueue);
}

WTF::Vector<WTF::String>JavaBridge::getSupportedKeyStrengthList() {
    WTF::Vector<WTF::String> list;
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return list;
    jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(),
            mGetKeyStrengthList);
    int count = env->GetArrayLength(array);
    for (int i = 0; i < count; ++i) {
        jstring keyStrength = (jstring) env->GetObjectArrayElement(array, i);
        list.append(jstringToWtfString(env, keyStrength));
        env->DeleteLocalRef(keyStrength);
    }
    env->DeleteLocalRef(array);
    checkException(env);
    return list;
}

WTF::String JavaBridge::getSignedPublicKeyAndChallengeString(unsigned index,
        const WTF::String& challenge, const WebCore::KURL& url) {
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return String();
    jstring jChallenge = wtfStringToJstring(env, challenge);
    const WTF::String& urlStr = url.string();
    jstring jUrl = wtfStringToJstring(env, urlStr);
    jstring key = (jstring) env->CallObjectMethod(obj.get(),
            mGetSignedPublicKey, index, jChallenge, jUrl);
    WTF::String ret = jstringToWtfString(env, key);
    env->DeleteLocalRef(jChallenge);
    env->DeleteLocalRef(jUrl);
    env->DeleteLocalRef(key);
    return ret;
}

WTF::String JavaBridge::resolveFilePathForContentUri(const WTF::String& uri) {
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject obj = javaObject(env);
    if (!obj.get())
        return String();
    jstring jUri = wtfStringToJstring(env, uri);
    jstring path = static_cast<jstring>(env->CallObjectMethod(obj.get(), mResolveFilePathForContentUri, jUri));
    WTF::String ret = jstringToWtfString(env, path);
    env->DeleteLocalRef(jUri);
    env->DeleteLocalRef(path);
    return ret;
}

// ----------------------------------------------------------------------------

void JavaBridge::Constructor(JNIEnv* env, jobject obj)
{
    JavaBridge* javaBridge = new JavaBridge(env, obj);
    env->SetIntField(obj, gJavaBridge_ObjectID, (jint)javaBridge);
}

void JavaBridge::Finalize(JNIEnv* env, jobject obj)
{
    JavaBridge* javaBridge = (JavaBridge*)
        (env->GetIntField(obj, gJavaBridge_ObjectID));    
    ALOG_ASSERT(javaBridge, "Finalize should not be called twice for the same java bridge!");
    ALOGV("webcore_javabridge::nativeFinalize(%p)\n", javaBridge);
    delete javaBridge;
    env->SetIntField(obj, gJavaBridge_ObjectID, 0);
}

// we don't use the java bridge object, as we're just looking at a global
void JavaBridge::SharedTimerFired(JNIEnv* env, jobject)
{
    if (sSharedTimerFiredCallback)
        sSharedTimerFiredCallback();
}

void JavaBridge::SetCacheSize(JNIEnv* env, jobject obj, jint bytes)
{
    WebCore::memoryCache()->setCapacities(0, bytes/2, bytes);
}

void JavaBridge::SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online)
{
	WebCore::networkStateNotifier().networkStateChange(online);
}

void JavaBridge::SetNetworkType(JNIEnv* env, jobject obj, jstring javatype, jstring javasubtype)
{
    DEFINE_STATIC_LOCAL(AtomicString, wifi, ("wifi"));
    DEFINE_STATIC_LOCAL(AtomicString, mobile, ("mobile"));
    DEFINE_STATIC_LOCAL(AtomicString, mobileSupl, ("mobile_supl"));
    DEFINE_STATIC_LOCAL(AtomicString, gprs, ("gprs"));
    DEFINE_STATIC_LOCAL(AtomicString, edge, ("edge"));
    DEFINE_STATIC_LOCAL(AtomicString, umts, ("umts"));

    String type = jstringToWtfString(env, javatype);
    String subtype = jstringToWtfString(env, javasubtype);
    Connection::ConnectionType connectionType = Connection::UNKNOWN;
    if (type == wifi)
        connectionType = Connection::WIFI;
    else if (type == mobile || type == mobileSupl) {
        if (subtype == edge || subtype == gprs)
            connectionType = Connection::CELL_2G;
        else if (subtype == umts)
            connectionType = Connection::CELL_3G;
    }
    WebCore::networkStateNotifier().networkTypeChange(connectionType);
}

void JavaBridge::ServiceFuncPtrQueue(JNIEnv*)
{
    JavaSharedClient::ServiceFunctionPtrQueue();
}

void JavaBridge::UpdatePluginDirectories(JNIEnv* env, jobject obj,
        jobjectArray array, jboolean reload) {
    WTF::Vector<WTF::String> directories;
    int count = env->GetArrayLength(array);
    for (int i = 0; i < count; i++) {
        jstring dir = (jstring) env->GetObjectArrayElement(array, i);
        directories.append(jstringToWtfString(env, dir));
        env->DeleteLocalRef(dir);
    }
    checkException(env);
    WebCore::PluginDatabase *pluginDatabase =
            WebCore::PluginDatabase::installedPlugins();
    pluginDatabase->setPluginDirectories(directories);
    // refreshPlugins() should refresh both PluginDatabase and Page's PluginData
    WebCore::Page::refreshPlugins(reload);
}

void JavaBridge::AddPackageNames(JNIEnv* env, jobject obj, jobject packageNames)
{
    if (!packageNames)
        return;

    // dalvikvm will raise exception if any of these fail
    jclass setClass = env->FindClass("java/util/Set");
    jmethodID iterator = env->GetMethodID(setClass, "iterator",
            "()Ljava/util/Iterator;");
    jobject iter = env->CallObjectMethod(packageNames, iterator);

    jclass iteratorClass = env->FindClass("java/util/Iterator");
    jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
    jmethodID next = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");

    HashSet<WTF::String> namesSet;
    while (env->CallBooleanMethod(iter, hasNext)) {
        jstring name = static_cast<jstring>(env->CallObjectMethod(iter, next));
        namesSet.add(jstringToWtfString(env, name));
        env->DeleteLocalRef(name);
    }

    packageNotifier().addPackageNames(namesSet);

    env->DeleteLocalRef(iteratorClass);
    env->DeleteLocalRef(iter);
    env->DeleteLocalRef(setClass);
}

void JavaBridge::AddPackageName(JNIEnv* env, jobject obj, jstring packageName)
{
    packageNotifier().addPackageName(jstringToWtfString(env, packageName));
}

void JavaBridge::RemovePackageName(JNIEnv* env, jobject obj, jstring packageName)
{
    packageNotifier().removePackageName(jstringToWtfString(env, packageName));
}

void JavaBridge::UpdateProxy(JNIEnv* env, jobject obj, jstring newProxy, jstring newExList)
{
    std::string proxy = jstringToStdString(env, newProxy);
    std::string exList = jstringToStdString(env, newExList);
    WebCache::get(false)->proxy()->UpdateProxySettings(proxy, exList);
    WebCache::get(true)->proxy()->UpdateProxySettings(proxy, exList);
}


// ----------------------------------------------------------------------------

/*
 * JNI registration.
 */
static JNINativeMethod gWebCoreJavaBridgeMethods[] = {
    /* name, signature, funcPtr */
    { "nativeConstructor", "()V",
        (void*) JavaBridge::Constructor },
    { "nativeFinalize", "()V",
        (void*) JavaBridge::Finalize },
    { "sharedTimerFired", "()V",
        (void*) JavaBridge::SharedTimerFired },
    { "setCacheSize", "(I)V",
        (void*) JavaBridge::SetCacheSize },
    { "setNetworkOnLine", "(Z)V",
        (void*) JavaBridge::SetNetworkOnLine },
    { "setNetworkType", "(Ljava/lang/String;Ljava/lang/String;)V",
        (void*) JavaBridge::SetNetworkType },
    { "nativeServiceFuncPtrQueue", "()V",
        (void*) JavaBridge::ServiceFuncPtrQueue },
    { "nativeUpdatePluginDirectories", "([Ljava/lang/String;Z)V",
        (void*) JavaBridge::UpdatePluginDirectories },
    { "addPackageNames", "(Ljava/util/Set;)V",
        (void*) JavaBridge::AddPackageNames },
    { "addPackageName", "(Ljava/lang/String;)V",
        (void*) JavaBridge::AddPackageName },
    { "removePackageName", "(Ljava/lang/String;)V",
        (void*) JavaBridge::RemovePackageName },
    { "nativeUpdateProxy", "(Ljava/lang/String;Ljava/lang/String;)V",
        (void*) JavaBridge::UpdateProxy }
};

int registerJavaBridge(JNIEnv* env)
{
    jclass javaBridge = env->FindClass("android/webkit/JWebCoreJavaBridge");
    LOG_FATAL_IF(javaBridge == NULL, "Unable to find class android/webkit/JWebCoreJavaBridge");
    gJavaBridge_ObjectID = env->GetFieldID(javaBridge, "mNativeBridge", "I");
    LOG_FATAL_IF(gJavaBridge_ObjectID == NULL, "Unable to find android/webkit/JWebCoreJavaBridge.mNativeBridge");
    env->DeleteLocalRef(javaBridge);

    return jniRegisterNativeMethods(env, "android/webkit/JWebCoreJavaBridge", 
                                    gWebCoreJavaBridgeMethods, NELEM(gWebCoreJavaBridgeMethods));
}

} /* namespace android */
