/*
 * Copyright (C) 2008 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.
 */

#define LOG_TAG "UEventObserver"
//#define LOG_NDEBUG 0

#include "utils/Log.h"

#include "hardware_legacy/uevent.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"

#include <utils/Mutex.h>
#include <utils/Vector.h>
#include <utils/String8.h>
#include <nativehelper/ScopedUtfChars.h>

namespace android {

static Mutex gMatchesMutex;
static Vector<String8> gMatches;

static void nativeSetup(JNIEnv *env, jclass clazz) {
    if (!uevent_init()) {
        jniThrowException(env, "java/lang/RuntimeException",
                "Unable to open socket for UEventObserver");
    }
}

static bool isMatch(const char* buffer, size_t length) {
    AutoMutex _l(gMatchesMutex);

    for (size_t i = 0; i < gMatches.size(); i++) {
        const String8& match = gMatches.itemAt(i);

        // Consider all zero-delimited fields of the buffer.
        const char* field = buffer;
        const char* end = buffer + length + 1;
        do {
            if (strstr(field, match.string())) {
                ALOGV("Matched uevent message with pattern: %s", match.string());
                return true;
            }
            field += strlen(field) + 1;
        } while (field != end);
    }
    return false;
}

static jstring nativeWaitForNextEvent(JNIEnv *env, jclass clazz) {
    char buffer[1024];

    for (;;) {
        int length = uevent_next_event(buffer, sizeof(buffer) - 1);
        if (length <= 0) {
            return NULL;
        }
        buffer[length] = '\0';

        ALOGV("Received uevent message: %s", buffer);

        if (isMatch(buffer, length)) {
            // Assume the message is ASCII.
            jchar message[length];
            for (int i = 0; i < length; i++) {
                message[i] = buffer[i];
            }
            return env->NewString(message, length);
        }
    }
}

static void nativeAddMatch(JNIEnv* env, jclass clazz, jstring matchStr) {
    ScopedUtfChars match(env, matchStr);

    AutoMutex _l(gMatchesMutex);
    gMatches.add(String8(match.c_str()));
}

static void nativeRemoveMatch(JNIEnv* env, jclass clazz, jstring matchStr) {
    ScopedUtfChars match(env, matchStr);

    AutoMutex _l(gMatchesMutex);
    for (size_t i = 0; i < gMatches.size(); i++) {
        if (gMatches.itemAt(i) == match.c_str()) {
            gMatches.removeAt(i);
            break; // only remove first occurrence
        }
    }
}

static const JNINativeMethod gMethods[] = {
    { "nativeSetup", "()V",
            (void *)nativeSetup },
    { "nativeWaitForNextEvent", "()Ljava/lang/String;",
            (void *)nativeWaitForNextEvent },
    { "nativeAddMatch", "(Ljava/lang/String;)V",
            (void *)nativeAddMatch },
    { "nativeRemoveMatch", "(Ljava/lang/String;)V",
            (void *)nativeRemoveMatch },
};


int register_android_os_UEventObserver(JNIEnv *env)
{
    FindClassOrDie(env, "android/os/UEventObserver");

    return RegisterMethodsOrDie(env, "android/os/UEventObserver", gMethods, NELEM(gMethods));
}

}   // namespace android
