/*
 * Copyright (C) 2007 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 "NativeRegEx"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "unicode/uregex.h"
#include "unicode/utypes.h"
#include "unicode/parseerr.h"

#include <jni.h>
#include <JNIHelp.h>

static jchar EMPTY_STRING = 0;

/**
 * A data structure that ties together an ICU regular expression and the
 * character data it refers to (but does not have a copy of), so we can
 * manage memory properly.
 */
struct RegExData {
    // A pointer to the ICU regular expression
    URegularExpression* regex;
    // A pointer to (a copy of) the input text that *we* manage
    jchar* text;
};

static void throwPatternSyntaxException(JNIEnv* env, UErrorCode status,
                                        jstring pattern, UParseError error)
{
    jclass clazz = env->FindClass("java/util/regex/PatternSyntaxException");
    jmethodID method = env->GetMethodID(clazz, "<init>",
                                    "(Ljava/lang/String;Ljava/lang/String;I)V");

    jstring message = env->NewStringUTF(u_errorName(status));
    jthrowable except = (jthrowable)(env->NewObject(clazz, method, message,
                                                    pattern, error.offset));
    env->Throw(except);
}

static void throwRuntimeException(JNIEnv* env, UErrorCode status) {
    jniThrowRuntimeException(env, u_errorName(status));
}

static void _close(JNIEnv*, jclass, RegExData* data)
{
    if (data->regex != NULL) {
        uregex_close(data->regex);
    }

    if (data->text != &EMPTY_STRING) {
        delete[] data->text;
    }

    free(data);
}

static RegExData* open(JNIEnv* env, jclass clazz, jstring pattern, jint flags)
{
    flags = flags | UREGEX_ERROR_ON_UNKNOWN_ESCAPES;

    RegExData* data = (RegExData*)calloc(sizeof(RegExData), 1);

    UErrorCode status = U_ZERO_ERROR;
    UParseError error;
    error.offset = -1;

    int patternLen = env->GetStringLength(pattern);
    if (patternLen == 0) {
        data->regex = uregex_open(&EMPTY_STRING, -1, flags, &error, &status);
    } else {
        jchar const * patternRaw = env->GetStringChars(pattern, NULL);
        data->regex = uregex_open(patternRaw, patternLen, flags, &error,
                                  &status);
        env->ReleaseStringChars(pattern, patternRaw);
    }

    if (!U_SUCCESS(status)) {
        _close(env, clazz, data);
        throwPatternSyntaxException(env, status, pattern, error);
        data = NULL;
    }

    return data;
}

static RegExData* _clone(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;

    URegularExpression* clonedRegex = uregex_clone(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }

    RegExData* result = (RegExData*)calloc(sizeof(RegExData), 1);
    result->regex = clonedRegex;

    return result;
}

static void setText(JNIEnv* env, jclass, RegExData* data, jstring text)
{
    UErrorCode status = U_ZERO_ERROR;

    uregex_setText(data->regex, &EMPTY_STRING, 0, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
        return;
    }

    if (data->text != &EMPTY_STRING) {
        delete[] data->text;
        data->text = NULL;
    }

    int textLen = env->GetStringLength(text);
    if (textLen == 0) {
        data->text = &EMPTY_STRING;
    } else {
        data->text = new jchar[textLen + 1];
        env->GetStringRegion(text, 0, textLen, data->text);
        data->text[textLen] = 0;
    }

    uregex_setText(data->regex, data->text, textLen, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
}

static jboolean matches(JNIEnv* env, jclass, RegExData* data,
                        jint startIndex)
{
    UErrorCode status = U_ZERO_ERROR;

    jboolean result = uregex_matches(data->regex, startIndex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }

    return result;
}

static jboolean lookingAt(JNIEnv* env, jclass, RegExData* data,
                          jint startIndex)
{
    UErrorCode status = U_ZERO_ERROR;

    jboolean result = uregex_lookingAt(data->regex, startIndex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }

    return result;
}

static jboolean find(JNIEnv* env, jclass, RegExData* data,
                     jint startIndex)
{
    UErrorCode status = U_ZERO_ERROR;

    jboolean result = uregex_find(data->regex, startIndex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }

    return result;
}

static jboolean findNext(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;

    jboolean result = uregex_findNext(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }

    return result;
}

static jint groupCount(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;

    jint result = uregex_groupCount(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }

    return result;
}

static void startEnd(JNIEnv* env, jclass, RegExData* data,
                     jintArray offsets)
{
    UErrorCode status = U_ZERO_ERROR;

    jint * offsetsRaw = env->GetIntArrayElements(offsets, NULL);

    int groupCount = uregex_groupCount(data->regex, &status);
    for (int i = 0; i <= groupCount && U_SUCCESS(status); i++) {
        offsetsRaw[2 * i + 0] = uregex_start(data->regex, i, &status);
        offsetsRaw[2 * i + 1] = uregex_end(data->regex, i, &status);
    }

    env->ReleaseIntArrayElements(offsets, offsetsRaw, 0);

    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
}

static void setRegion(JNIEnv* env, jclass, RegExData* data, jint start,
                      jint end)
{
    UErrorCode status = U_ZERO_ERROR;
    uregex_setRegion(data->regex, start, end, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
}

static jint regionStart(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;
    int result = uregex_regionStart(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
    return result;
}

static jint regionEnd(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;
    int result = uregex_regionEnd(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
    return result;
}

static void useTransparentBounds(JNIEnv* env, jclass, RegExData* data,
                                 jboolean value)
{
    UErrorCode status = U_ZERO_ERROR;
    uregex_useTransparentBounds(data->regex, value, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
}

static jboolean hasTransparentBounds(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;
    jboolean result = uregex_hasTransparentBounds(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
    return result;
}

static void useAnchoringBounds(JNIEnv* env, jclass, RegExData* data,
                               jboolean value)
{
    UErrorCode status = U_ZERO_ERROR;
    uregex_useAnchoringBounds(data->regex, value, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
}

static jboolean hasAnchoringBounds(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;
    jboolean result = uregex_hasAnchoringBounds(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
    return result;
}

static jboolean hitEnd(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;
    jboolean result = uregex_hitEnd(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
    return result;
}

static jboolean requireEnd(JNIEnv* env, jclass, RegExData* data)
{
    UErrorCode status = U_ZERO_ERROR;
    jboolean result = uregex_requireEnd(data->regex, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
    return result;
}

static void reset(JNIEnv* env, jclass, RegExData* data, jint position)
{
    UErrorCode status = U_ZERO_ERROR;
    uregex_reset(data->regex, position, &status);
    if (!U_SUCCESS(status)) {
        throwRuntimeException(env, status);
    }
}

static JNINativeMethod gMethods[] = {
    { "open",                 "(Ljava/lang/String;I)I", (void*)open       },
    { "clone",                "(I)I",                   (void*)_clone     },
    { "close",                "(I)V",                   (void*)_close     },
    { "setText",              "(ILjava/lang/String;)V", (void*)setText    },
    { "matches",              "(II)Z",                  (void*)matches    },
    { "lookingAt",            "(II)Z",                  (void*)lookingAt  },
    { "find",                 "(II)Z",                  (void*)find       },
    { "findNext",             "(I)Z",                   (void*)findNext   },
    { "groupCount",           "(I)I",                   (void*)groupCount },
    { "startEnd",             "(I[I)V",                 (void*)startEnd   },
    { "setRegion",            "(III)V",                 (void*)setRegion  },
    { "regionStart",          "(I)I",                   (void*)regionStart },
    { "regionEnd",            "(I)I",                   (void*)regionEnd  },
    { "useTransparentBounds", "(IZ)V",            (void*)useTransparentBounds },
    { "hasTransparentBounds", "(I)Z",             (void*)hasTransparentBounds },
    { "useAnchoringBounds",   "(IZ)V",            (void*)useAnchoringBounds },
    { "hasAnchoringBounds",   "(I)Z",             (void*)hasAnchoringBounds },
    { "hitEnd",               "(I)Z",                   (void*)hitEnd },
    { "requireEnd",           "(I)Z",                   (void*)requireEnd },
    { "reset",                "(II)V",                  (void*)reset },
};
int register_com_ibm_icu4jni_regex_NativeRegEx(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/regex/NativeRegEx",
            gMethods, NELEM(gMethods));
}
