/*
 * 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)
        }
    }
}
