/*
 * Copyright 2021 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.
 */

@file:Suppress("UnstableApiUsage")

package androidx.build.lint

import androidx.build.lint.Stubs.Companion.RestrictTo
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class BanUncheckedReflectionTest :
    AbstractLintDetectorTest(
        useDetector = BanUncheckedReflection(),
        useIssues = listOf(BanUncheckedReflection.ISSUE),
        stubs = arrayOf(Stubs.ChecksSdkIntAtLeast),
    ) {

    @Test
    fun `Detection of unchecked reflection in real-world Java sources`() {
        val input = arrayOf(javaSample("androidx.sample.core.app.ActivityRecreator"), RestrictTo)

        val expected =
            """
src/androidx/sample/core/app/ActivityRecreator.java:261: Error: Method.invoke requires both an upper and lower SDK bounds checks to be safe, and the upper bound must be below SdkVersionInfo.HIGHEST_KNOWN_API. [BanUncheckedReflection]
                        performStopActivity3ParamsMethod.invoke(activityThread,
                        ^
src/androidx/sample/core/app/ActivityRecreator.java:264: Error: Method.invoke requires both an upper and lower SDK bounds checks to be safe, and the upper bound must be below SdkVersionInfo.HIGHEST_KNOWN_API. [BanUncheckedReflection]
                        performStopActivity2ParamsMethod.invoke(activityThread,
                        ^
2 errors, 0 warnings
        """
                .trimIndent()

        check(*input).expect(expected)
    }

    @Test
    fun `Detection of unchecked reflection in real-world Kotlin sources`() {
        val input = arrayOf(ktSample("androidx.sample.core.app.ActivityRecreatorKt"), RestrictTo)

        val expected =
            """
src/androidx/sample/core/app/ActivityRecreatorKt.kt:172: Error: Method.invoke requires both an upper and lower SDK bounds checks to be safe, and the upper bound must be below SdkVersionInfo.HIGHEST_KNOWN_API. [BanUncheckedReflection]
                        performStopActivity3ParamsMethod!!.invoke(
                        ^
src/androidx/sample/core/app/ActivityRecreatorKt.kt:179: Error: Method.invoke requires both an upper and lower SDK bounds checks to be safe, and the upper bound must be below SdkVersionInfo.HIGHEST_KNOWN_API. [BanUncheckedReflection]
                        performStopActivity2ParamsMethod!!.invoke(activityThread, token, false)
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors, 0 warnings
        """
                .trimIndent()

        lint().files(*input).run().expect(expected)
    }

    @Test
    fun `Checked reflection in real-world Java sources`() {
        val input =
            arrayOf(javaSample("androidx.sample.core.app.ActivityRecreatorChecked"), RestrictTo)

        val expected =
            """
No warnings.
        """
                .trimIndent()

        check(*input).expect(expected)
    }

    @Test
    fun `Checked reflection in real-world Kotlin sources`() {
        val input =
            arrayOf(ktSample("androidx.sample.core.app.ActivityRecreatorKtChecked"), RestrictTo)

        check(*input).expectClean()
    }

    @Test
    fun `Checked reflection using preceding if with return`() {
        val input =
            kotlin(
                """
            package androidx.foo

            import android.os.Build

            fun forceEnablePlatformTracing() {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return
                if (Build.VERSION.SDK_INT >= 29) return
                val method = android.os.Trace::class.java.getMethod(
                    "setAppTracingAllowed",
                    Boolean::class.javaPrimitiveType
                )
                method.invoke(null, true)
            }
        """
                    .trimIndent()
            )

        check(input).expectClean()
    }

    @Test
    fun `Checked reflection using @DeprecatedSinceApi method`() {
        val input =
            arrayOf(
                kotlin(
                    """
            package androidx.foo

            import android.os.Build
            import androidx.annotation.DeprecatedSinceApi

            @DeprecatedSinceApi(29)
            fun forceEnablePlatformTracing() {
                val method = android.os.Trace::class.java.getMethod(
                    "setAppTracingAllowed",
                    Boolean::class.javaPrimitiveType
                )
                method.invoke(null, true)
            }
        """
                        .trimIndent()
                ),
                Stubs.DeprecatedSinceApi
            )

        check(*input).expectClean()
    }

    @Test
    fun `Checked reflection using @DeprecatedSinceApi class`() {
        val input =
            arrayOf(
                java(
                    """
            package androidx.foo;

            import android.os.Build;
            import androidx.annotation.DeprecatedSinceApi;

            public class OuterClass {
                public static void doCheckedReflection() {
                    if (Build.VERSION.SDK_INT < 29) {
                        PreApi29Impl.forceEnablePlatformTracing();
                    }
                }

                @DeprecatedSinceApi(29)
                static class PreApi29Impl {
                    public static void forceEnablePlatformTracing() {
                        android.os.Trace.class.getMethod(
                            "setAppTracingAllowed",
                            Boolean.class
                        ).invoke(null, true);
                    }
                }
            }
        """
                        .trimIndent()
                ),
                Stubs.DeprecatedSinceApi
            )

        check(*input).expectClean()
    }

    @Test
    fun `Checked reflection using Kotlin range check`() {
        val input =
            arrayOf(
                kotlin(
                    """
                package androidx.foo

                import android.os.Build

                fun forceEnablePlatformTracing() {
                    if (Build.VERSION.SDK_INT in 18..28) {
                        val method = android.os.Trace::class.java.getMethod(
                            "setAppTracingAllowed",
                            Boolean::class.javaPrimitiveType
                        )
                        method.invoke(null, true)
                    }
                }
            """
                        .trimIndent()
                )
            )

        check(*input).expectClean()
    }
}
