/* //device/libs/android_runtime/android_util_FileObserver.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
#include "core_jni_helpers.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>

#if defined(__linux__)
#include <sys/inotify.h>
#endif

namespace android {

static jmethodID method_onEvent;

static jint android_os_fileobserver_init(JNIEnv* env, jobject object)
{
#if defined(__linux__)
    return (jint)inotify_init1(IN_CLOEXEC);
#else
    return -1;
#endif
}

static void android_os_fileobserver_observe(JNIEnv* env, jobject object, jint fd)
{
#if defined(__linux__)

    char event_buf[512];
    struct inotify_event* event;

    while (1)
    {
        int event_pos = 0;
        int num_bytes = read(fd, event_buf, sizeof(event_buf));

        if (num_bytes < (int)sizeof(*event))
        {
            if (errno == EINTR)
                continue;

            ALOGE("***** ERROR! android_os_fileobserver_observe() got a short event!");
            return;
        }

        while (num_bytes >= (int)sizeof(*event))
        {
            int event_size;
            event = (struct inotify_event *)(event_buf + event_pos);

            jstring path = NULL;

            if (event->len > 0)
            {
                path = env->NewStringUTF(event->name);
            }

            env->CallVoidMethod(object, method_onEvent, event->wd, event->mask, path);
            if (env->ExceptionCheck()) {
                env->ExceptionDescribe();
                env->ExceptionClear();
            }
            if (path != NULL)
            {
                env->DeleteLocalRef(path);
            }

            event_size = sizeof(*event) + event->len;
            num_bytes -= event_size;
            event_pos += event_size;
        }
    }

#endif
}

static void android_os_fileobserver_startWatching(JNIEnv* env, jobject object, jint fd,
                                                       jobjectArray pathStrings, jint mask,
                                                       jintArray wfdArray)
{
    ScopedIntArrayRW wfds(env, wfdArray);
    if (wfds.get() == nullptr) {
        jniThrowException(env, "java/lang/IllegalStateException", "Failed to get ScopedIntArrayRW");
    }

#if defined(__linux__)

    if (fd >= 0)
    {
        size_t count = wfds.size();
        for (jsize i = 0; i < count; ++i) {
            jstring pathString = (jstring) env->GetObjectArrayElement(pathStrings, i);

            ScopedUtfChars path(env, pathString);

            wfds[i] = inotify_add_watch(fd, path.c_str(), mask);
        }
    }

#endif
}

static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object,
                                                 jint fd, jintArray wfdArray)
{
#if defined(__linux__)

    ScopedIntArrayRO wfds(env, wfdArray);
    if (wfds.get() == nullptr) {
        jniThrowException(env, "java/lang/IllegalStateException", "Failed to get ScopedIntArrayRO");
    }
    size_t count = wfds.size();
    for (size_t i = 0; i < count; ++i) {
        inotify_rm_watch((int)fd, (uint32_t)wfds[i]);
    }

#endif
}

static const JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
    { "init", "()I", (void*)android_os_fileobserver_init },
    { "observe", "(I)V", (void*)android_os_fileobserver_observe },
    { "startWatching", "(I[Ljava/lang/String;I[I)V", (void*)android_os_fileobserver_startWatching },
    { "stopWatching", "(I[I)V", (void*)android_os_fileobserver_stopWatching }

};

int register_android_os_FileObserver(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, "android/os/FileObserver$ObserverThread");

    method_onEvent = GetMethodIDOrDie(env, clazz, "onEvent", "(IILjava/lang/String;)V");

    return RegisterMethodsOrDie(env, "android/os/FileObserver$ObserverThread", sMethods,
                                NELEM(sMethods));
}

} /* namespace android */
