#include <vector>

#include "Gainmap.h"
#include "GraphicsJNI.h"
#include "SkBitmap.h"
#include "SkBlendMode.h"
#include "SkColor.h"
#include "SkColorFilter.h"
#include "SkGradientShader.h"
#include "SkImage.h"
#include "SkImagePriv.h"
#include "SkMatrix.h"
#include "SkPoint.h"
#include "SkRefCnt.h"
#include "SkSamplingOptions.h"
#include "SkScalar.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkTileMode.h"
#include "effects/GainmapRenderer.h"
#include "include/effects/SkRuntimeEffect.h"

using namespace android::uirenderer;

/**
 * By default Skia gradients will interpolate their colors in unpremul space
 * and then premultiply each of the results. We must set this flag to preserve
 * backwards compatibility by premultiplying the colors of the gradient first,
 * and then interpolating between them.
 */
static const uint32_t sGradientShaderFlags = SkGradientShader::kInterpolateColorsInPremul_Flag;

#define ThrowIAE_IfNull(env, ptr)   \
    if (nullptr == ptr) {           \
        doThrowIAE(env);            \
        return 0;                   \
    }

static void Color_RGBToHSV(JNIEnv* env, jobject, jint red, jint green, jint blue, jfloatArray hsvArray)
{
    SkScalar hsv[3];
    SkRGBToHSV(red, green, blue, hsv);

    AutoJavaFloatArray  autoHSV(env, hsvArray, 3);
    float* values = autoHSV.ptr();
    for (int i = 0; i < 3; i++) {
        values[i] = SkScalarToFloat(hsv[i]);
    }
}

static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvArray)
{
    AutoJavaFloatArray  autoHSV(env, hsvArray, 3);
    SkScalar* hsv = autoHSV.ptr();
    return static_cast<jint>(SkHSVToColor(alpha, hsv));
}

///////////////////////////////////////////////////////////////////////////////////////////////

static void Shader_safeUnref(SkShader* shader) {
    SkSafeUnref(shader);
}

static jlong Shader_getNativeFinalizer(JNIEnv*, jobject) {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
}

///////////////////////////////////////////////////////////////////////////////////////////////

static SkGainmapInfo sNoOpGainmap = {
        .fGainmapRatioMin = {1.f, 1.f, 1.f, 1.0},
        .fGainmapRatioMax = {1.f, 1.f, 1.f, 1.0},
        .fGainmapGamma = {1.f, 1.f, 1.f, 1.f},
        .fEpsilonSdr = {0.f, 0.f, 0.f, 1.0},
        .fEpsilonHdr = {0.f, 0.f, 0.f, 1.0},
        .fDisplayRatioSdr = 1.f,
        .fDisplayRatioHdr = 1.f,
};

static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
                                      jint tileModeX, jint tileModeY, jint maxAniso, bool filter,
                                      bool isDirectSampled, jlong overrideGainmapPtr) {
    SkSamplingOptions sampling = maxAniso > 0 ? SkSamplingOptions::Aniso(static_cast<int>(maxAniso))
                                              : SkSamplingOptions(filter ? SkFilterMode::kLinear
                                                                         : SkFilterMode::kNearest,
                                                                  SkMipmapMode::kNone);
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    const Gainmap* gainmap = reinterpret_cast<Gainmap*>(overrideGainmapPtr);
    sk_sp<SkImage> image;
    if (bitmapHandle) {
        // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
        // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
        auto& bitmap = android::bitmap::toBitmap(bitmapHandle);
        image = bitmap.makeImage();
        if (!gainmap && bitmap.hasGainmap()) {
            gainmap = bitmap.gainmap().get();
        }

        if (!isDirectSampled && gainmap && gainmap->info != sNoOpGainmap) {
            sk_sp<SkShader> gainmapShader =
                    MakeGainmapShader(image, gainmap->bitmap->makeImage(), gainmap->info,
                                      (SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
            if (gainmapShader) {
                if (matrix) {
                    gainmapShader = gainmapShader->makeWithLocalMatrix(*matrix);
                }
                return reinterpret_cast<jlong>(gainmapShader.release());
            }
        }
    }

    if (!image.get()) {
        SkBitmap bitmap;
        image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
    }

    sk_sp<SkShader> shader;
    if (isDirectSampled) {
        shader = image->makeRawShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
    } else {
        shader = image->makeShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
    }
    ThrowIAE_IfNull(env, shader.get());

    if (matrix) {
        shader = shader->makeWithLocalMatrix(*matrix);
    }

    return reinterpret_cast<jlong>(shader.release());
}

///////////////////////////////////////////////////////////////////////////////////////////////

static std::vector<SkColor4f> convertColorLongs(JNIEnv* env, jlongArray colorArray) {
    const size_t count = env->GetArrayLength(colorArray);
    const jlong* colorValues = env->GetLongArrayElements(colorArray, nullptr);

    std::vector<SkColor4f> colors(count);
    for (size_t i = 0; i < count; ++i) {
        colors[i] = GraphicsJNI::convertColorLong(colorValues[i]);
    }

    env->ReleaseLongArrayElements(colorArray, const_cast<jlong*>(colorValues), JNI_ABORT);
    return colors;
}

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong LinearGradient_create(JNIEnv* env, jobject, jlong matrixPtr,
        jfloat x0, jfloat y0, jfloat x1, jfloat y1, jlongArray colorArray,
        jfloatArray posArray, jint tileMode, jlong colorSpaceHandle) {
    SkPoint pts[2];
    pts[0].set(x0, y0);
    pts[1].set(x1, y1);

    std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);

    AutoJavaFloatArray autoPos(env, posArray, colors.size());
    SkScalar* pos = autoPos.ptr();

    sk_sp<SkShader> shader(SkGradientShader::MakeLinear(pts, &colors[0],
                GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
                static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr));
    ThrowIAE_IfNull(env, shader);

    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    if (matrix) {
        shader = shader->makeWithLocalMatrix(*matrix);
    }

    return reinterpret_cast<jlong>(shader.release());
}

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong RadialGradient_create(JNIEnv* env,
        jobject,
        jlong matrixPtr,
        jfloat startX,
        jfloat startY,
        jfloat startRadius,
        jfloat endX,
        jfloat endY,
        jfloat endRadius,
        jlongArray colorArray,
        jfloatArray posArray,
        jint tileMode,
        jlong colorSpaceHandle) {

    SkPoint start;
    start.set(startX, startY);

    SkPoint end;
    end.set(endX, endY);

    std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);

    AutoJavaFloatArray autoPos(env, posArray, colors.size());
    SkScalar* pos = autoPos.ptr();

    auto colorSpace = GraphicsJNI::getNativeColorSpace(colorSpaceHandle);
    auto skTileMode = static_cast<SkTileMode>(tileMode);
    sk_sp<SkShader> shader = SkGradientShader::MakeTwoPointConical(start, startRadius, end,
                    endRadius, &colors[0], std::move(colorSpace), pos, colors.size(), skTileMode,
                    sGradientShaderFlags, nullptr);
    ThrowIAE_IfNull(env, shader);

    // Explicitly create a new shader with the specified matrix to match existing behavior.
    // Passing in the matrix in the instantiation above can throw exceptions for non-invertible
    // matrices. However, makeWithLocalMatrix will still allow for the shader to be created
    // and skia handles null-shaders internally (i.e. is ignored)
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    if (matrix) {
        shader = shader->makeWithLocalMatrix(*matrix);
    }

    return reinterpret_cast<jlong>(shader.release());
}

///////////////////////////////////////////////////////////////////////////////

static jlong SweepGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
        jlongArray colorArray, jfloatArray jpositions, jlong colorSpaceHandle) {
    std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);

    AutoJavaFloatArray autoPos(env, jpositions, colors.size());
    SkScalar* pos = autoPos.ptr();

    sk_sp<SkShader> shader = SkGradientShader::MakeSweep(x, y, &colors[0],
            GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
            sGradientShaderFlags, nullptr);
    ThrowIAE_IfNull(env, shader);

    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    if (matrix) {
        shader = shader->makeWithLocalMatrix(*matrix);
    }

    return reinterpret_cast<jlong>(shader.release());
}

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
        jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle) {
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
    SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
    SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
    sk_sp<SkShader> baseShader(SkShaders::Blend(mode,
            sk_ref_sp(shaderA), sk_ref_sp(shaderB)));

    SkShader* shader;

    if (matrix) {
        shader = baseShader->makeWithLocalMatrix(*matrix).release();
    } else {
        shader = baseShader.release();
    }
    return reinterpret_cast<jlong>(shader);
}

///////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////

static jlong RuntimeShader_createShaderBuilder(JNIEnv* env, jobject, jstring sksl) {
    ScopedUtfChars strSksl(env, sksl);
    auto result = SkRuntimeEffect::MakeForShader(SkString(strSksl.c_str()),
                                                 SkRuntimeEffect::Options{});
    if (result.effect.get() == nullptr) {
        doThrowIAE(env, result.errorText.c_str());
        return 0;
    }
    return reinterpret_cast<jlong>(new SkRuntimeShaderBuilder(std::move(result.effect)));
}

static void SkRuntimeShaderBuilder_delete(SkRuntimeShaderBuilder* builder) {
    delete builder;
}

static jlong RuntimeShader_getNativeFinalizer(JNIEnv*, jobject) {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SkRuntimeShaderBuilder_delete));
}

static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderBuilder, jlong matrixPtr) {
    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
    sk_sp<SkShader> shader = builder->makeShader(matrix);
    ThrowIAE_IfNull(env, shader);
    return reinterpret_cast<jlong>(shader.release());
}

static inline int ThrowIAEFmt(JNIEnv* env, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    int ret = jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", fmt, args);
    va_end(args);
    return ret;
}

static bool isIntUniformType(const SkRuntimeEffect::Uniform::Type& type) {
    switch (type) {
        case SkRuntimeEffect::Uniform::Type::kFloat:
        case SkRuntimeEffect::Uniform::Type::kFloat2:
        case SkRuntimeEffect::Uniform::Type::kFloat3:
        case SkRuntimeEffect::Uniform::Type::kFloat4:
        case SkRuntimeEffect::Uniform::Type::kFloat2x2:
        case SkRuntimeEffect::Uniform::Type::kFloat3x3:
        case SkRuntimeEffect::Uniform::Type::kFloat4x4:
            return false;
        case SkRuntimeEffect::Uniform::Type::kInt:
        case SkRuntimeEffect::Uniform::Type::kInt2:
        case SkRuntimeEffect::Uniform::Type::kInt3:
        case SkRuntimeEffect::Uniform::Type::kInt4:
            return true;
    }
}

static void UpdateFloatUniforms(JNIEnv* env, SkRuntimeShaderBuilder* builder,
                                const char* uniformName, const float values[], int count,
                                bool isColor) {
    SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(uniformName);
    if (uniform.fVar == nullptr) {
        ThrowIAEFmt(env, "unable to find uniform named %s", uniformName);
    } else if (isColor != ((uniform.fVar->flags & SkRuntimeEffect::Uniform::kColor_Flag) != 0)) {
        if (isColor) {
            jniThrowExceptionFmt(
                    env, "java/lang/IllegalArgumentException",
                    "attempting to set a color uniform using the non-color specific APIs: %s %x",
                    uniformName, uniform.fVar->flags);
        } else {
            ThrowIAEFmt(env,
                        "attempting to set a non-color uniform using the setColorUniform APIs: %s",
                        uniformName);
        }
    } else if (isIntUniformType(uniform.fVar->type)) {
        ThrowIAEFmt(env, "attempting to set a int uniform using the setUniform APIs: %s",
                    uniformName);
    } else if (!uniform.set<float>(values, count)) {
        ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]",
                    uniform.fVar->sizeInBytes(), sizeof(float) * count);
    }
}

static void RuntimeShader_updateFloatUniforms(JNIEnv* env, jobject, jlong shaderBuilder,
                                              jstring jUniformName, jfloat value1, jfloat value2,
                                              jfloat value3, jfloat value4, jint count) {
    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
    ScopedUtfChars name(env, jUniformName);
    const float values[4] = {value1, value2, value3, value4};
    UpdateFloatUniforms(env, builder, name.c_str(), values, count, false);
}

static void RuntimeShader_updateFloatArrayUniforms(JNIEnv* env, jobject, jlong shaderBuilder,
                                                   jstring jUniformName, jfloatArray jvalues,
                                                   jboolean isColor) {
    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
    ScopedUtfChars name(env, jUniformName);
    AutoJavaFloatArray autoValues(env, jvalues, 0, kRO_JNIAccess);
    UpdateFloatUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length(), isColor);
}

static void UpdateIntUniforms(JNIEnv* env, SkRuntimeShaderBuilder* builder, const char* uniformName,
                              const int values[], int count) {
    SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(uniformName);
    if (uniform.fVar == nullptr) {
        ThrowIAEFmt(env, "unable to find uniform named %s", uniformName);
    } else if (!isIntUniformType(uniform.fVar->type)) {
        ThrowIAEFmt(env, "attempting to set a non-int uniform using the setIntUniform APIs: %s",
                    uniformName);
    } else if (!uniform.set<int>(values, count)) {
        ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]",
                    uniform.fVar->sizeInBytes(), sizeof(float) * count);
    }
}

static void RuntimeShader_updateIntUniforms(JNIEnv* env, jobject, jlong shaderBuilder,
                                            jstring jUniformName, jint value1, jint value2,
                                            jint value3, jint value4, jint count) {
    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
    ScopedUtfChars name(env, jUniformName);
    const int values[4] = {value1, value2, value3, value4};
    UpdateIntUniforms(env, builder, name.c_str(), values, count);
}

static void RuntimeShader_updateIntArrayUniforms(JNIEnv* env, jobject, jlong shaderBuilder,
                                                 jstring jUniformName, jintArray jvalues) {
    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
    ScopedUtfChars name(env, jUniformName);
    AutoJavaIntArray autoValues(env, jvalues, 0);
    UpdateIntUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length());
}

static void RuntimeShader_updateShader(JNIEnv* env, jobject, jlong shaderBuilder,
                                           jstring jUniformName, jlong shaderHandle) {
    SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
    ScopedUtfChars name(env, jUniformName);
    SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);

    SkRuntimeShaderBuilder::BuilderChild child = builder->child(name.c_str());
    if (child.fChild == nullptr) {
        ThrowIAEFmt(env, "unable to find shader named %s", name.c_str());
        return;
    }

    builder->child(name.c_str()) = sk_ref_sp(shader);
}

///////////////////////////////////////////////////////////////////////////////////////////////

static const JNINativeMethod gColorMethods[] = {
    { "nativeRGBToHSV",    "(III[F)V", (void*)Color_RGBToHSV   },
    { "nativeHSVToColor",  "(I[F)I",   (void*)Color_HSVToColor }
};

static const JNINativeMethod gShaderMethods[] = {
    { "nativeGetFinalizer",   "()J",    (void*)Shader_getNativeFinalizer },
};

static const JNINativeMethod gBitmapShaderMethods[] = {
        {"nativeCreate", "(JJIIIZZJ)J", (void*)BitmapShader_constructor},

};

static const JNINativeMethod gLinearGradientMethods[] = {
    { "nativeCreate",     "(JFFFF[J[FIJ)J",  (void*)LinearGradient_create     },
};

static const JNINativeMethod gRadialGradientMethods[] = {
    { "nativeCreate",     "(JFFFFFF[J[FIJ)J",  (void*)RadialGradient_create     },
};

static const JNINativeMethod gSweepGradientMethods[] = {
    { "nativeCreate",     "(JFF[J[FJ)J",  (void*)SweepGradient_create     },
};

static const JNINativeMethod gComposeShaderMethods[] = {
    { "nativeCreate",      "(JJJI)J",   (void*)ComposeShader_create     },
};

static const JNINativeMethod gRuntimeShaderMethods[] = {
        {"nativeGetFinalizer", "()J", (void*)RuntimeShader_getNativeFinalizer},
        {"nativeCreateShader", "(JJ)J", (void*)RuntimeShader_create},
        {"nativeCreateBuilder", "(Ljava/lang/String;)J", (void*)RuntimeShader_createShaderBuilder},
        {"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V",
         (void*)RuntimeShader_updateFloatArrayUniforms},
        {"nativeUpdateUniforms", "(JLjava/lang/String;FFFFI)V",
         (void*)RuntimeShader_updateFloatUniforms},
        {"nativeUpdateUniforms", "(JLjava/lang/String;[I)V",
         (void*)RuntimeShader_updateIntArrayUniforms},
        {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
         (void*)RuntimeShader_updateIntUniforms},
        {"nativeUpdateShader", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateShader},
};

int register_android_graphics_Shader(JNIEnv* env)
{
    android::RegisterMethodsOrDie(env, "android/graphics/Color", gColorMethods,
                                  NELEM(gColorMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/Shader", gShaderMethods,
                                  NELEM(gShaderMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/BitmapShader", gBitmapShaderMethods,
                                  NELEM(gBitmapShaderMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/LinearGradient", gLinearGradientMethods,
                                  NELEM(gLinearGradientMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/RadialGradient", gRadialGradientMethods,
                                  NELEM(gRadialGradientMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/SweepGradient", gSweepGradientMethods,
                                  NELEM(gSweepGradientMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/ComposeShader", gComposeShaderMethods,
                                  NELEM(gComposeShaderMethods));
    android::RegisterMethodsOrDie(env, "android/graphics/RuntimeShader", gRuntimeShaderMethods,
                                  NELEM(gRuntimeShaderMethods));

    return 0;
}
