/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <android/log.h>
#include <jni.h>

#include "include/core/SkM44.h"
#include "include/effects/SkRuntimeEffect.h"
#include "modules/androidkit/src/Utils.h"

namespace {

static jlong ShaderBuilder_Create(JNIEnv* env, jobject, jstring jsksl) {
    auto [eff,err] = SkRuntimeEffect::MakeForShader(
                         SkString(androidkit::utils::CString(env, jsksl)));

    if (!eff) {
        // TODO: throw exception?
        __android_log_print(ANDROID_LOG_ERROR, "AndroidKit", "Failed to compile shader: %s\n",
                            err.c_str());
        return 0;
    }

    return reinterpret_cast<jlong>(new SkRuntimeShaderBuilder(std::move(eff)));
}

static void ShaderBuilder_Release(JNIEnv* env, jobject, jlong native_instance) {
    if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
        delete builder;
    }
}

static void ShaderBuilder_SetUniformFloat(JNIEnv* env, jobject, jlong native_instance, jstring jname, float val) {
    if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
        builder->uniform(androidkit::utils::CString(env, jname)) = val;
    }
}

static void ShaderBuilder_SetUniformFloat3(JNIEnv* env, jobject, jlong native_instance, jstring jname, float valX, float valY, float valZ) {
    if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
        builder->uniform(androidkit::utils::CString(env, jname)) = SkV3{valX, valY, valZ};
    }
}

static void ShaderBuilder_SetUniformMatrix(JNIEnv* env, jobject, jlong native_instance, jstring jname, jlong native_matrix) {
    if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
        if (auto* matrix = reinterpret_cast<SkM44*>(native_matrix)) {
            builder->uniform(androidkit::utils::CString(env, jname)) = *matrix;
        }
    }
}

static jlong ShaderBuilder_MakeShader(JNIEnv* env, jobject, jlong native_instance) {
    if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
        auto shader = builder->makeShader();
        return reinterpret_cast<jlong>(shader.release());
    }

    return 0;
}

}  // namespace

int register_androidkit_RuntimeShaderBuilder(JNIEnv* env) {
    static const JNINativeMethod methods[] = {
        {"nCreate"          , "(Ljava/lang/String;)J"       , reinterpret_cast<void*>(ShaderBuilder_Create)},
        {"nRelease"         , "(J)V"                        , reinterpret_cast<void*>(ShaderBuilder_Release)},

        {"nSetUniformFloat" , "(JLjava/lang/String;F)V"     , reinterpret_cast<void*>(ShaderBuilder_SetUniformFloat)},
        {"nSetUniformFloat3", "(JLjava/lang/String;FFF)V"   , reinterpret_cast<void*>(ShaderBuilder_SetUniformFloat3)},
        {"nSetUniformMatrix", "(JLjava/lang/String;J)V"     , reinterpret_cast<void*>(ShaderBuilder_SetUniformMatrix)},
        {"nMakeShader"      , "(J)J"                        , reinterpret_cast<void*>(ShaderBuilder_MakeShader)},
    };

    const auto clazz = env->FindClass("org/skia/androidkit/RuntimeShaderBuilder");
    return clazz
        ? env->RegisterNatives(clazz, methods, std::size(methods))
        : JNI_ERR;
}
