/*
 * Copyright (C) 2018 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.SdkConstants.ATTR_VALUE
import com.android.tools.lint.client.api.UElementHandler
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.ConstantEvaluator
import com.android.tools.lint.detector.api.Detector
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.LintFix
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import org.jetbrains.uast.UAnnotated
import org.jetbrains.uast.UClass
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMethod
import java.util.EnumSet

/**
 * It checks that there is a reason defined when using the @Ignored annotation from JUnit.
 */
class IgnoreWithoutReasonDetector : Detector(), Detector.UastScanner {
    companion object {
        @JvmField
        val ISSUE = Issue.create(
            id = "IgnoreWithoutReason",
            briefDescription = "@Ignore without Reason",
            explanation = """
            Ignoring a test without a reason makes it difficult to figure out the problem later.
            Please define an explicit reason why it is ignored, and when it can be resolved.""",
            category = Category.TESTING,
            priority = 2,
            severity = Severity.WARNING,
            implementation = Implementation(
                IgnoreWithoutReasonDetector::class.java,
                EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES),
                Scope.JAVA_FILE_SCOPE
            )
        )
    }

    override fun getApplicableUastTypes(): List<Class<out UElement>> =
        listOf(UMethod::class.java, UClass::class.java)

    override fun createUastHandler(context: JavaContext): UElementHandler = IgnoreAnnotationVisitor(context)

    internal class IgnoreAnnotationVisitor(private val context: JavaContext) : UElementHandler() {
        override fun visitMethod(node: UMethod) = processAnnotations(node, node)

        override fun visitClass(node: UClass) = processAnnotations(node, node)

        private fun processAnnotations(element: UElement, annotated: UAnnotated) {
            val annotations = context.evaluator.getAllAnnotations(annotated, false)
            val ignoreAnnotation = annotations.firstOrNull { it.qualifiedName == "org.junit.Ignore" }

            if (ignoreAnnotation != null) {
                val attribute = ignoreAnnotation.findAttributeValue(ATTR_VALUE)
                val hasDescription =
                    attribute != null &&
                    run {
                        val value = ConstantEvaluator.evaluate(context, attribute) as? String
                        value != null && value.isNotBlank() && value != "TODO"
                    }
                if (!hasDescription) {
                    val fix =
                        if (attribute == null || ignoreAnnotation.attributeValues.isEmpty()) {
                            LintFix.create()
                                .name("Give reason")
                                .replace()
                                .end()
                                .with("(\"TODO\")")
                                .select("TODO")
                                .build()
                        } else {
                            null
                        }
                    context.report(ISSUE, element, context.getLocation(ignoreAnnotation),
                        "Test is ignored without giving any explanation.", fix)
                }
            }
        }
    }
}
