/*
 * Copyright (C) 2017 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 <sstream>
#include <unordered_map>
#include <vector>

#include <jni.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativetesthelper_jni/utils.h>
#include <gtest/gtest.h>

static JavaVM* gVm = nullptr;
JavaVM* GetJavaVM() {
    return gVm;
}
static void RegisterJavaVm(JNIEnv* env) {
    (void)env->GetJavaVM(&gVm);
}

namespace {

struct {
    jclass clazz;

    /** static methods **/
    jmethodID createTestDescription;

    /** methods **/
    jmethodID addChild;
} gDescription;

struct {
    jclass clazz;

    jmethodID fireTestStarted;
    jmethodID fireTestIgnored;
    jmethodID fireTestFailure;
    jmethodID fireTestFinished;

} gRunNotifier;

struct {
    jclass clazz;
    jmethodID ctor;
} gAssertionFailure;

struct {
    jclass clazz;
    jmethodID ctor;
} gFailure;

jobject gEmptyAnnotationsArray;

struct TestNameInfo {
    std::string nativeName;
    bool run;
};
// Maps mangled test names to native test names.
std::unordered_map<std::string, TestNameInfo> gNativeTestNames;

// Return the full native test name as a Java method name, which does not allow
// slashes or dots. Store the original name for later lookup.
std::string registerAndMangleTestName(const std::string& nativeName) {
    std::string mangledName = nativeName;
    std::replace(mangledName.begin(), mangledName.end(), '.', '_');
    std::replace(mangledName.begin(), mangledName.end(), '/', '_');
    gNativeTestNames.insert(std::make_pair(mangledName, TestNameInfo{nativeName, false}));
    return mangledName;
}

// Creates org.junit.runner.Description object for a GTest given its name.
jobject createTestDescription(JNIEnv* env, jstring className, const std::string& mangledName) {
    ScopedLocalRef<jstring> jTestName(env, env->NewStringUTF(mangledName.c_str()));
    return env->CallStaticObjectMethod(gDescription.clazz, gDescription.createTestDescription,
            className, jTestName.get(), gEmptyAnnotationsArray);
}

jobject createTestDescription(JNIEnv* env, jstring className, const char* testCaseName, const char* testName) {
    std::ostringstream nativeNameStream;
    nativeNameStream << testCaseName << "." << testName;
    std::string mangledName = registerAndMangleTestName(nativeNameStream.str());
    return createTestDescription(env, className, mangledName);
}

void addChild(JNIEnv* env, jobject description, jobject childDescription) {
    env->CallVoidMethod(description, gDescription.addChild, childDescription);
}


class JUnitNotifyingListener : public ::testing::EmptyTestEventListener {
public:

    JUnitNotifyingListener(JNIEnv* env, jstring className, jobject runNotifier)
            : mEnv(env)
            , mRunNotifier(runNotifier)
            , mClassName(className)
            , mCurrentTestDescription{env, nullptr}
    {}
    virtual ~JUnitNotifyingListener() {}

    virtual void OnTestStart(const testing::TestInfo &testInfo) override {
        mCurrentTestDescription.reset(
                createTestDescription(mEnv, mClassName, testInfo.test_case_name(), testInfo.name()));
        notify(gRunNotifier.fireTestStarted);
    }

    virtual void OnTestPartResult(const testing::TestPartResult &testPartResult) override {
        if (!testPartResult.passed()) {
            mCurrentTestError << "\n" << testPartResult.file_name() << ":" << testPartResult.line_number()
                          << "\n" << testPartResult.message() << "\n";
        }
    }

    virtual void OnTestEnd(const testing::TestInfo&) override {
        const std::string error = mCurrentTestError.str();

        if (!error.empty()) {
            ScopedLocalRef<jstring> jmessage(mEnv, mEnv->NewStringUTF(error.c_str()));
            ScopedLocalRef<jobject> jthrowable(mEnv, mEnv->NewObject(gAssertionFailure.clazz,
                    gAssertionFailure.ctor, jmessage.get()));
            ScopedLocalRef<jobject> jfailure(mEnv, mEnv->NewObject(gFailure.clazz,
                    gFailure.ctor, mCurrentTestDescription.get(), jthrowable.get()));
            mEnv->CallVoidMethod(mRunNotifier, gRunNotifier.fireTestFailure, jfailure.get());
        }

        notify(gRunNotifier.fireTestFinished);
        mCurrentTestDescription.reset();
        mCurrentTestError.str("");
        mCurrentTestError.clear();
    }

    void reportDisabledTests(const std::vector<std::string>& mangledNames) {
        for (const std::string& mangledName : mangledNames) {
            mCurrentTestDescription.reset(createTestDescription(mEnv, mClassName, mangledName));
            notify(gRunNotifier.fireTestIgnored);
            mCurrentTestDescription.reset();
        }
    }

private:
    void notify(jmethodID method) {
        mEnv->CallVoidMethod(mRunNotifier, method, mCurrentTestDescription.get());
    }

    JNIEnv* mEnv;
    jobject mRunNotifier;
    jstring mClassName;
    ScopedLocalRef<jobject> mCurrentTestDescription;
    std::ostringstream mCurrentTestError;
};

}  // namespace

extern "C"
JNIEXPORT void JNICALL
Java_com_android_gtestrunner_GtestRunner_nInitialize(JNIEnv *env, jclass, jstring className, jobject suite) {
    RegisterJavaVm(env);

    // Initialize gtest, removing the default result printer
    int argc = 1;
    const char* argv[] = { "gtest_wrapper" };
    ::testing::InitGoogleTest(&argc, (char**) argv);

    auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
    delete listeners.Release(listeners.default_result_printer());

    gDescription.clazz = (jclass) env->NewGlobalRef(env->FindClass("org/junit/runner/Description"));
    gDescription.createTestDescription = env->GetStaticMethodID(gDescription.clazz, "createTestDescription",
            "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/annotation/Annotation;)Lorg/junit/runner/Description;");
    gDescription.addChild = env->GetMethodID(gDescription.clazz, "addChild",
            "(Lorg/junit/runner/Description;)V");

    jclass annotations = env->FindClass("java/lang/annotation/Annotation");
    gEmptyAnnotationsArray = env->NewGlobalRef(env->NewObjectArray(0, annotations, nullptr));
    gNativeTestNames.clear();

    gAssertionFailure.clazz = (jclass) env->NewGlobalRef(env->FindClass("java/lang/AssertionError"));
    gAssertionFailure.ctor = env->GetMethodID(gAssertionFailure.clazz, "<init>", "(Ljava/lang/Object;)V");

    gFailure.clazz = (jclass) env->NewGlobalRef(env->FindClass("org/junit/runner/notification/Failure"));
    gFailure.ctor = env->GetMethodID(gFailure.clazz, "<init>",
            "(Lorg/junit/runner/Description;Ljava/lang/Throwable;)V");

    gRunNotifier.clazz = (jclass) env->NewGlobalRef(
            env->FindClass("org/junit/runner/notification/RunNotifier"));
    gRunNotifier.fireTestStarted = env->GetMethodID(gRunNotifier.clazz, "fireTestStarted",
            "(Lorg/junit/runner/Description;)V");
    gRunNotifier.fireTestIgnored = env->GetMethodID(gRunNotifier.clazz, "fireTestIgnored",
            "(Lorg/junit/runner/Description;)V");
    gRunNotifier.fireTestFinished = env->GetMethodID(gRunNotifier.clazz, "fireTestFinished",
            "(Lorg/junit/runner/Description;)V");
    gRunNotifier.fireTestFailure = env->GetMethodID(gRunNotifier.clazz, "fireTestFailure",
            "(Lorg/junit/runner/notification/Failure;)V");

    auto unitTest = ::testing::UnitTest::GetInstance();
    for (int testCaseIndex = 0; testCaseIndex < unitTest->total_test_case_count(); testCaseIndex++) {
        auto testCase = unitTest->GetTestCase(testCaseIndex);
        for (int testIndex = 0; testIndex < testCase->total_test_count(); testIndex++) {
            auto testInfo = testCase->GetTestInfo(testIndex);
            ScopedLocalRef<jobject> testDescription(env,
                    createTestDescription(env, className, testCase->name(), testInfo->name()));
            addChild(env, suite, testDescription.get());
        }
    }
}

extern "C"
JNIEXPORT void JNICALL
Java_com_android_gtestrunner_GtestRunner_nAddTest(JNIEnv *env, jclass, jstring testName) {
    const char* testNameChars = env->GetStringUTFChars(testName, JNI_FALSE);
    auto found = gNativeTestNames.find(testNameChars);
    if (found != gNativeTestNames.end()) {
        found->second.run = true;
    }
    env->ReleaseStringUTFChars(testName, testNameChars);
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_android_gtestrunner_GtestRunner_nRun(JNIEnv *env, jclass, jstring className, jobject notifier) {
    // Apply the test filter computed in Java-land. The filter is just a list of test names.
    std::ostringstream filterStream;
    std::vector<std::string> mangledNamesOfDisabledTests;
    for (const auto& entry : gNativeTestNames) {
        // If the test was not selected for running by the Java layer, ignore it completely.
        if (!entry.second.run) continue;
        // If the test has DISABLED_ at the beginning of its name, after a slash or after a dot,
        // report it as ignored (disabled) to the Java layer.
        if (entry.second.nativeName.find("DISABLED_") == 0 ||
                entry.second.nativeName.find("/DISABLED_") != std::string::npos ||
                entry.second.nativeName.find(".DISABLED_") != std::string::npos) {
            mangledNamesOfDisabledTests.push_back(entry.first);
            continue;
        }
        filterStream << entry.second.nativeName << ":";
    }
    std::string filter = filterStream.str();
    if (filter.empty()) {
        // If the string we built is empty, we don't want to run any tests, but GTest runs all tests
        // when an empty filter is passed. Replace an empty filter with a filter that matches nothing.
        filter = "-*";
    } else {
        // Removes the trailing colon.
        filter.pop_back();
    }
    ::testing::GTEST_FLAG(filter) = filter;

    auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
    JUnitNotifyingListener junitListener{env, className, notifier};
    listeners.Append(&junitListener);
    int success = RUN_ALL_TESTS();
    listeners.Release(&junitListener);
    junitListener.reportDisabledTests(mangledNamesOfDisabledTests);
    return success == 0;
}
