/*
 * Copyright (C) 2017 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.
 */

package com.android.tools.lint.checks

import com.android.tools.lint.checks.AnnotationDetector.CHECK_RESULT_ANNOTATION
import com.android.tools.lint.checks.AnnotationDetector.ERRORPRONE_CAN_IGNORE_RETURN_VALUE
import com.android.tools.lint.checks.AnnotationDetector.FINDBUGS_ANNOTATIONS_CHECK_RETURN_VALUE
import com.android.tools.lint.checks.AnnotationDetector.JAVAX_ANNOTATION_CHECK_RETURN_VALUE
import com.android.tools.lint.detector.api.AnnotationUsageType
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Implementation
import com.android.tools.lint.detector.api.Issue
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.android.tools.lint.detector.api.UastLintUtils.Companion.containsAnnotation
import com.android.tools.lint.detector.api.UastLintUtils.Companion.getAnnotationStringValue
import com.android.tools.lint.detector.api.isJava
import com.android.tools.lint.detector.api.isKotlin
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiType
import org.jetbrains.uast.UAnnotation
import org.jetbrains.uast.UBlockExpression
import org.jetbrains.uast.UClassInitializer
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.ULambdaExpression
import org.jetbrains.uast.UMethod
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.getParentOfType

class CheckResultDetector : AbstractAnnotationDetector(), SourceCodeScanner {
    override fun applicableAnnotations(): List<String> = listOf(
        CHECK_RESULT_ANNOTATION.oldName(),
        CHECK_RESULT_ANNOTATION.newName(),
        FINDBUGS_ANNOTATIONS_CHECK_RETURN_VALUE,
        JAVAX_ANNOTATION_CHECK_RETURN_VALUE,
        ERRORPRONE_CAN_IGNORE_RETURN_VALUE,
        "io.reactivex.annotations.CheckReturnValue",
        "com.google.errorprone.annotations.CheckReturnValue"
    )

    override fun visitAnnotationUsage(
        context: JavaContext,
        usage: UElement,
        type: AnnotationUsageType,
        annotation: UAnnotation,
        qualifiedName: String,
        method: PsiMethod?,
        referenced: PsiElement?,
        annotations: List<UAnnotation>,
        allMemberAnnotations: List<UAnnotation>,
        allClassAnnotations: List<UAnnotation>,
        allPackageAnnotations: List<UAnnotation>
    ) {
        method ?: return

        // Don't inherit CheckResult from packages for now; see
        //  https://issuetracker.google.com/69344103
        // for a common (dagger) package declaration that doesn't have
        // a @CanIgnoreReturnValue exclusion on inject.
        if (allPackageAnnotations.contains(annotation)) {
            return
        }

        if (qualifiedName == ERRORPRONE_CAN_IGNORE_RETURN_VALUE) {
            return
        }

        checkResult(
            context, usage, method, annotation,
            allMemberAnnotations, allClassAnnotations
        )
    }

    private fun checkResult(
        context: JavaContext,
        element: UElement,
        method: PsiMethod,
        annotation: UAnnotation,
        allMemberAnnotations: List<UAnnotation>,
        allClassAnnotations: List<UAnnotation>
    ) {
        if (isExpressionValueUnused(element)) {
            // If this CheckResult annotation is from a class, check to see
            // if it's been reversed with @CanIgnoreReturnValue
            if (containsAnnotation(allMemberAnnotations, ERRORPRONE_CAN_IGNORE_RETURN_VALUE) ||
                containsAnnotation(
                    allClassAnnotations,
                    ERRORPRONE_CAN_IGNORE_RETURN_VALUE
                )
            ) {
                return
            }

            if (method.returnType == PsiType.VOID) {
                return
            }

            val methodName = JavaContext.getMethodName(element)
            val suggested = getAnnotationStringValue(
                annotation,
                AnnotationDetector.ATTR_SUGGEST
            )

            // Failing to check permissions is a potential security issue (and had an existing
            // dedicated issue id before which people may already have configured with a
            // custom severity in their LintOptions etc) so continue to use that issue
            // (which also has category Security rather than Correctness) for these:
            var issue = CHECK_RESULT
            if (methodName != null && methodName.startsWith("check") &&
                methodName.contains("Permission")
            ) {
                issue = CHECK_PERMISSION
            }

            var message = String.format(
                "The result of `%1\$s` is not used",
                methodName
            )
            if (suggested != null) {
                // TODO: Resolve suggest attribute (e.g. prefix annotation class if it starts
                // with "#" etc?
                message = String.format(
                    "The result of `%1\$s` is not used; did you mean to call `%2\$s`?",
                    methodName, suggested
                )
            } else if ("intersect" == methodName && context.evaluator.isMemberInClass(
                    method,
                    "android.graphics.Rect"
                )
            ) {
                message += ". If the rectangles do not intersect, no change is made and the " +
                        "original rectangle is not modified. These methods return false to " +
                        "indicate that this has happened."
            }

            val fix = if (suggested != null) {
                fix().data(suggested)
            } else {
                null
            }

            val location = context.getLocation(element)
            report(context, issue, element, location, message, fix)
        }
    }

    private fun isExpressionValueUnused(element: UElement): Boolean {
        var prev = element.getParentOfType<UExpression>(
            UExpression::class.java, false
        ) ?: return true

        var curr = prev.uastParent ?: return true
        while (curr is UQualifiedReferenceExpression && curr.selector === prev) {
            prev = curr
            curr = curr.uastParent ?: return true
        }

        @Suppress("RedundantIf")
        if (curr is UBlockExpression) {
            if (curr.uastParent is ULambdaExpression && isKotlin(curr.sourcePsi)) {
                // Lambda block: for now assume used (e.g. parameter
                // in call. Later consider recursing here to
                // detect if the lambda itself is unused.
                return false
            }

            // In Java, it's apparent when an expression is unused:
            // the parent is a block expression. However, in Kotlin it's
            // much trickier: values can flow through blocks and up through
            // if statements, try statements.
            //
            // In Kotlin, we consider an expression unused if its parent
            // is not a block, OR, the expression is not the last statement
            // in the block, OR, recursively the parent expression is not
            // used (e.g. you're in an if, but that if statement is itself
            // not doing anything with the value.)
            val block = curr
            val expression = prev
            val index = block.expressions.indexOf(expression)
            if (index == -1) {
                return true
            }

            if (index < block.expressions.size - 1) {
                // Not last child
                return true
            }

            if (isJava(curr.sourcePsi)) {
                // In Java there's no implicit passing to the parent
                return true
            }

            // It's the last child: see if the parent is unused
            val parent = curr.uastParent ?: return true
            if (parent is UMethod || parent is UClassInitializer) {
                return true
            }
            return isExpressionValueUnused(parent)
        } else if (curr is UMethod && curr.isConstructor) {
            return true
        } else {
            // Some other non block node type, such as assignment,
            // method declaration etc: not unused
            // TODO: Make sure that a void/unit method inline declaration
            // works correctly
            return false
        }
    }

    companion object {
        private val IMPLEMENTATION = Implementation(
            CheckResultDetector::class.java,
            Scope.JAVA_FILE_SCOPE
        )

        /** Method result should be used  */
        @JvmField
        val CHECK_RESULT = Issue.create(
            id = "CheckResult",
            briefDescription = "Ignoring results",
            explanation = """
                Some methods have no side effects, and calling them without doing something \
                without the result is suspicious.""",
            category = Category.CORRECTNESS,
            priority = 6,
            severity = Severity.WARNING,
            implementation = IMPLEMENTATION
        )

        /** Failing to enforce security by just calling check permission  */
        @JvmField
        val CHECK_PERMISSION = Issue.create(
            id = "UseCheckPermission",
            briefDescription = "Using the result of check permission calls",
            explanation = """
                You normally want to use the result of checking a permission; these methods \
                return whether the permission is held; they do not throw an error if the \
                permission is not granted. Code which does not do anything with the return \
                value probably meant to be calling the enforce methods instead, e.g. rather \
                than `Context#checkCallingPermission` it should call \
                `Context#enforceCallingPermission`.""",
            category = Category.SECURITY,
            priority = 6,
            severity = Severity.WARNING,
            androidSpecific = true,
            implementation = IMPLEMENTATION
        )
    }
}
