/*
 * Copyright (C) 2016 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 specic language governing permissions and
 * limitations under the License.
 */

// Need to use LOGE_EX.
#define LOG_TAG "AppFuseBridge"

#include <android_runtime/Log.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <core_jni_helpers.h>
#include <libappfuse/FuseBridgeLoop.h>
#include <libappfuse/FuseBuffer.h>
#include <nativehelper/JNIHelp.h>

namespace android {
namespace {

constexpr const char* CLASS_NAME = "com/android/server/storage/AppFuseBridge";
static jclass gAppFuseClass;
static jmethodID gAppFuseOnMount;
static jmethodID gAppFuseOnClosed;

class Callback : public fuse::FuseBridgeLoopCallback {
    JNIEnv* mEnv;
    jobject mSelf;

public:
    Callback(JNIEnv* env, jobject self) : mEnv(env), mSelf(self) {}
    void OnMount(int mount_id) override {
        mEnv->CallVoidMethod(mSelf, gAppFuseOnMount, mount_id);
        if (mEnv->ExceptionCheck()) {
            LOGE_EX(mEnv, nullptr);
            mEnv->ExceptionClear();
        }
    }

    void OnClosed(int mount_id) override {
        mEnv->CallVoidMethod(mSelf, gAppFuseOnClosed, mount_id);
        if (mEnv->ExceptionCheck()) {
            LOGE_EX(mEnv, nullptr);
            mEnv->ExceptionClear();
        }
    }
};

class MonitorScope final {
public:
    MonitorScope(JNIEnv* env, jobject obj) : mEnv(env), mObj(obj), mLocked(false) {
        if (mEnv->MonitorEnter(obj) == JNI_OK) {
            mLocked = true;
        } else {
            LOG(ERROR) << "Failed to enter monitor.";
        }
    }

    ~MonitorScope() {
        if (mLocked) {
            if (mEnv->MonitorExit(mObj) != JNI_OK) {
                LOG(ERROR) << "Failed to exit monitor.";
            }
        }
    }

    explicit operator bool() {
        return mLocked;
    }

private:
    // Lifetime of |MonitorScope| must be shorter than the reference of mObj.
    JNIEnv* mEnv;
    jobject mObj;
    bool mLocked;

    DISALLOW_COPY_AND_ASSIGN(MonitorScope);
};

jlong com_android_server_storage_AppFuseBridge_new(JNIEnv* env, jobject self) {
    return reinterpret_cast<jlong>(new fuse::FuseBridgeLoop());
}

void com_android_server_storage_AppFuseBridge_delete(JNIEnv* env, jobject self, jlong java_loop) {
    fuse::FuseBridgeLoop* const loop = reinterpret_cast<fuse::FuseBridgeLoop*>(java_loop);
    CHECK(loop);
    delete loop;
}

void com_android_server_storage_AppFuseBridge_start_loop(
        JNIEnv* env, jobject self, jlong java_loop) {
    fuse::FuseBridgeLoop* const loop = reinterpret_cast<fuse::FuseBridgeLoop*>(java_loop);
    CHECK(loop);
    Callback callback(env, self);
    loop->Start(&callback);
}

jint com_android_server_storage_AppFuseBridge_add_bridge(
        JNIEnv* env, jobject self, jlong java_loop, jint mountId, jint javaDevFd) {
    base::unique_fd devFd(javaDevFd);
    fuse::FuseBridgeLoop* const loop = reinterpret_cast<fuse::FuseBridgeLoop*>(java_loop);
    CHECK(loop);

    base::unique_fd proxyFd[2];
    if (!fuse::SetupMessageSockets(&proxyFd)) {
        return -1;
    }

    if (!loop->AddBridge(mountId, std::move(devFd), std::move(proxyFd[0]))) {
        return -1;
    }

    return proxyFd[1].release();
}

const JNINativeMethod methods[] = {
    {
        "native_new",
        "()J",
        reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_new)
    },
    {
        "native_delete",
        "(J)V",
        reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_delete)
    },
    {
        "native_start_loop",
        "(J)V",
        reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_start_loop)
    },
    {
        "native_add_bridge",
        "(JII)I",
        reinterpret_cast<void*>(com_android_server_storage_AppFuseBridge_add_bridge)
    }
};

}  // namespace

void register_android_server_storage_AppFuse(JNIEnv* env) {
    CHECK(env != nullptr);

    gAppFuseClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, CLASS_NAME));
    gAppFuseOnMount = GetMethodIDOrDie(env, gAppFuseClass, "onMount", "(I)V");
    gAppFuseOnClosed = GetMethodIDOrDie(env, gAppFuseClass, "onClosed", "(I)V");
    RegisterMethodsOrDie(env, CLASS_NAME, methods, NELEM(methods));
}
}  // namespace android
