/*
 * Copyright (C) 2012 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.CLASS_FRAGMENT
import com.android.SdkConstants.CLASS_V4_FRAGMENT
import com.android.tools.lint.detector.api.Category
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.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import org.jetbrains.uast.UAnonymousClass
import org.jetbrains.uast.UClass

/**
 * Checks that Fragment subclasses can be instantiated via
 * Class.newInstance: the class is public, static, and has a public null
 * constructor.
 *
 * This helps track down issues like
 * http://stackoverflow.com/questions/8058809/fragment-activity-crashes-on-screen-rotate
 * (and countless duplicates)
 */
class FragmentDetector : Detector(), SourceCodeScanner {
    companion object {
        /** Are fragment subclasses instantiatable? */
        @JvmField
        val ISSUE = Issue.create(
            id = "ValidFragment",
            briefDescription = "Fragment not instantiatable",
            explanation = """
                From the Fragment documentation:
                **Every** fragment must have an empty constructor, so it can be instantiated \
                when restoring its activity's state. It is strongly recommended that subclasses \
                do not have other constructors with parameters, since these constructors will \
                not be called when the fragment is re-instantiated; instead, arguments can be \
                supplied by the caller with `setArguments(Bundle)` and later retrieved by the \
                Fragment with `getArguments()`.

                Note that this is no longer true when you are using \
                `androidx.fragment.app.Fragment`; with the `FragmentFactory` you can supply \
                any arguments you want (as of version androidx version 1.1).
                """,
            category = Category.CORRECTNESS,
            androidSpecific = true,
            priority = 6,
            severity = Severity.ERROR,
            moreInfo = "https://developer.android.com/reference/android/app/Fragment.html#Fragment()",
            implementation = Implementation(FragmentDetector::class.java, Scope.JAVA_FILE_SCOPE)
        )
    }

    // ---- implements SourceCodeScanner ----

    override fun applicableSuperClasses(): List<String> {
        // Note: We are deliberately NOT including: CLASS_V4_FRAGMENT.newName() here:
        // androidx Fragments are allowed to use non-default constructors (see issue 119675579)
        return listOf(CLASS_FRAGMENT, CLASS_V4_FRAGMENT.oldName())
    }

    override fun visitClass(context: JavaContext, declaration: UClass) {
        if (declaration is UAnonymousClass) {
            context.report(
                ISSUE, declaration, context.getNameLocation(declaration),
                "Fragments should be static such that they can be re-instantiated by the system, and anonymous classes are not static"
            )
            return
        }

        val evaluator = context.evaluator
        if (evaluator.isAbstract(declaration)) {
            return
        }

        if (!evaluator.isPublic(declaration)) {
            context.report(
                ISSUE, declaration, context.getNameLocation(declaration),
                "This fragment class should be public (${declaration.qualifiedName})"
            )
            return
        }

        if (declaration.containingClass != null && !evaluator.isStatic(declaration)) {
            context.report(
                ISSUE, declaration, context.getNameLocation(declaration),
                "This fragment inner class should be static (${declaration.qualifiedName})"
            )
            return
        }

        var hasDefaultConstructor = false
        var hasConstructor = false
        for (constructor in declaration.constructors) {
            hasConstructor = true
            if (constructor.parameterList.parametersCount == 0) {
                if (evaluator.isPublic(constructor)) {
                    hasDefaultConstructor = true
                } else {
                    val location = context.getNameLocation(constructor)
                    context.report(
                        ISSUE, constructor, location, "The default constructor must be public"
                    )
                    return
                }
            } else {
                val location = context.getNameLocation(constructor)
                // TODO: Use separate issue for this which isn't an error
                val message =
                    "Avoid non-default constructors in fragments: use a default constructor plus `Fragment#setArguments(Bundle)` instead"
                context.report(ISSUE, constructor, location, message)
            }
        }

        if (!hasDefaultConstructor && hasConstructor) {
            val message =
                "This fragment should provide a default constructor (a public constructor with no arguments) (`${declaration.qualifiedName}`)"
            context.report(ISSUE, declaration, context.getNameLocation(declaration), message)
        }
    }
}
