/*
 * Copyright (C) 2022 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 <SkMesh.h>

#include "GraphicsJNI.h"
#include "graphics_jni_helpers.h"

namespace android {

using Attribute = SkMeshSpecification::Attribute;
using Varying = SkMeshSpecification::Varying;

static struct {
    jclass clazz{};
    jfieldID type{};
    jfieldID offset{};
    jfieldID name{};
} gAttributeInfo;

static struct {
    jclass clazz{};
    jfieldID type{};
    jfieldID name{};
} gVaryingInfo;

std::vector<Attribute> extractAttributes(JNIEnv* env, jobjectArray attributes) {
    int size = env->GetArrayLength(attributes);
    std::vector<Attribute> attVector;
    attVector.reserve(size);
    for (int i = 0; i < size; i++) {
        jobject attribute = env->GetObjectArrayElement(attributes, i);
        auto name = (jstring)env->GetObjectField(attribute, gAttributeInfo.name);
        auto attName = ScopedUtfChars(env, name);
        Attribute temp{Attribute::Type(env->GetIntField(attribute, gAttributeInfo.type)),
                       static_cast<size_t>(env->GetIntField(attribute, gAttributeInfo.offset)),
                       SkString(attName.c_str())};
        attVector.push_back(std::move(temp));
    }
    return attVector;
}

std::vector<Varying> extractVaryings(JNIEnv* env, jobjectArray varyings) {
    int size = env->GetArrayLength(varyings);
    std::vector<Varying> varyVector;
    varyVector.reserve(size);
    for (int i = 0; i < size; i++) {
        jobject varying = env->GetObjectArrayElement(varyings, i);
        auto name = (jstring)env->GetObjectField(varying, gVaryingInfo.name);
        auto varyName = ScopedUtfChars(env, name);
        Varying temp{Varying::Type(env->GetIntField(varying, gVaryingInfo.type)),
                     SkString(varyName.c_str())};
        varyVector.push_back(std::move(temp));
    }

    return varyVector;
}

static jlong Make(JNIEnv* env, jobject thiz, jobjectArray attributeArray, jint vertexStride,
                  jobjectArray varyingArray, jstring vertexShader, jstring fragmentShader) {
    auto attributes = extractAttributes(env, attributeArray);
    auto varyings = extractVaryings(env, varyingArray);
    auto skVertexShader = ScopedUtfChars(env, vertexShader);
    auto skFragmentShader = ScopedUtfChars(env, fragmentShader);
    auto meshSpecResult = SkMeshSpecification::Make(attributes, vertexStride, varyings,
                                                    SkString(skVertexShader.c_str()),
                                                    SkString(skFragmentShader.c_str()));
    if (meshSpecResult.specification.get() == nullptr) {
        jniThrowException(env, "java/lang/IllegalArgumentException", meshSpecResult.error.c_str());
    }

    return reinterpret_cast<jlong>(meshSpecResult.specification.release());
}

static jlong MakeWithCS(JNIEnv* env, jobject thiz, jobjectArray attributeArray, jint vertexStride,
                        jobjectArray varyingArray, jstring vertexShader, jstring fragmentShader,
                        jlong colorSpace) {
    auto attributes = extractAttributes(env, attributeArray);
    auto varyings = extractVaryings(env, varyingArray);
    auto skVertexShader = ScopedUtfChars(env, vertexShader);
    auto skFragmentShader = ScopedUtfChars(env, fragmentShader);
    auto meshSpecResult = SkMeshSpecification::Make(
            attributes, vertexStride, varyings, SkString(skVertexShader.c_str()),
            SkString(skFragmentShader.c_str()), GraphicsJNI::getNativeColorSpace(colorSpace));

    if (meshSpecResult.specification.get() == nullptr) {
        jniThrowException(env, "java/lang/IllegalArgumentException", meshSpecResult.error.c_str());
    }

    return reinterpret_cast<jlong>(meshSpecResult.specification.release());
}

static jlong MakeWithAlpha(JNIEnv* env, jobject thiz, jobjectArray attributeArray,
                           jint vertexStride, jobjectArray varyingArray, jstring vertexShader,
                           jstring fragmentShader, jlong colorSpace, jint alphaType) {
    auto attributes = extractAttributes(env, attributeArray);
    auto varyings = extractVaryings(env, varyingArray);
    auto skVertexShader = ScopedUtfChars(env, vertexShader);
    auto skFragmentShader = ScopedUtfChars(env, fragmentShader);
    auto meshSpecResult = SkMeshSpecification::Make(
            attributes, vertexStride, varyings, SkString(skVertexShader.c_str()),
            SkString(skFragmentShader.c_str()), GraphicsJNI::getNativeColorSpace(colorSpace),
            SkAlphaType(alphaType));

    if (meshSpecResult.specification.get() == nullptr) {
        jniThrowException(env, "java/lang/IllegalArgumentException", meshSpecResult.error.c_str());
    }

    return reinterpret_cast<jlong>(meshSpecResult.specification.release());
}

static void MeshSpecification_safeUnref(SkMeshSpecification* meshSpec) {
    SkSafeUnref(meshSpec);
}

static jlong getMeshSpecificationFinalizer() {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&MeshSpecification_safeUnref));
}

static const JNINativeMethod gMeshSpecificationMethods[] = {
        {"nativeGetFinalizer", "()J", (void*)getMeshSpecificationFinalizer},
        {"nativeMake",
         "([Landroid/graphics/MeshSpecification$Attribute;I[Landroid/graphics/"
         "MeshSpecification$Varying;"
         "Ljava/lang/String;Ljava/lang/String;)J",
         (void*)Make},
        {"nativeMakeWithCS",
         "([Landroid/graphics/MeshSpecification$Attribute;I"
         "[Landroid/graphics/MeshSpecification$Varying;Ljava/lang/String;Ljava/lang/String;J)J",
         (void*)MakeWithCS},
        {"nativeMakeWithAlpha",
         "([Landroid/graphics/MeshSpecification$Attribute;I"
         "[Landroid/graphics/MeshSpecification$Varying;Ljava/lang/String;Ljava/lang/String;JI)J",
         (void*)MakeWithAlpha}};

int register_android_graphics_MeshSpecification(JNIEnv* env) {
    android::RegisterMethodsOrDie(env, "android/graphics/MeshSpecification",
                                  gMeshSpecificationMethods, NELEM(gMeshSpecificationMethods));

    gAttributeInfo.clazz = env->FindClass("android/graphics/MeshSpecification$Attribute");
    gAttributeInfo.type = env->GetFieldID(gAttributeInfo.clazz, "mType", "I");
    gAttributeInfo.offset = env->GetFieldID(gAttributeInfo.clazz, "mOffset", "I");
    gAttributeInfo.name = env->GetFieldID(gAttributeInfo.clazz, "mName", "Ljava/lang/String;");

    gVaryingInfo.clazz = env->FindClass("android/graphics/MeshSpecification$Varying");
    gVaryingInfo.type = env->GetFieldID(gVaryingInfo.clazz, "mType", "I");
    gVaryingInfo.name = env->GetFieldID(gVaryingInfo.clazz, "mName", "Ljava/lang/String;");
    return 0;
}

}  // namespace android
