/*
 * Copyright (C) 2014 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.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.client.api.JavaEvaluator;
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 com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import java.util.Collections;
import java.util.List;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UastUtils;

/**
 * Checks that subclasses of certain APIs are overriding all methods that were abstract in one or
 * more earlier API levels that are still targeted by the minSdkVersion of this project.
 */
public class OverrideConcreteDetector extends Detector implements SourceCodeScanner {
    /** Are previously-abstract methods all overridden? */
    public static final Issue ISSUE =
            Issue.create(
                            "OverrideAbstract",
                            "Not overriding abstract methods on older platforms",
                            "To improve the usability of some APIs, some methods that used to be `abstract` have "
                                    + "been made concrete by adding default implementations. This means that when compiling "
                                    + "with new versions of the SDK, your code does not have to override these methods.\n"
                                    + "\n"
                                    + "However, if your code is also targeting older versions of the platform where these "
                                    + "methods were still `abstract`, the code will crash. You must override all methods "
                                    + "that used to be abstract in any versions targeted by your application's "
                                    + "`minSdkVersion`.",
                            Category.CORRECTNESS,
                            6,
                            Severity.ERROR,
                            new Implementation(
                                    OverrideConcreteDetector.class, Scope.JAVA_FILE_SCOPE))
                    .setAndroidSpecific(true);

    // This check is currently hardcoded for the specific case of the
    // NotificationListenerService change in API 21. We should consider
    // attempting to infer this information automatically from changes in
    // the API current.txt file and making this detector more database driven,
    // like the API detector.

    private static final String NOTIFICATION_LISTENER_SERVICE_FQN =
            "android.service.notification.NotificationListenerService";
    public static final String STATUS_BAR_NOTIFICATION_FQN =
            "android.service.notification.StatusBarNotification";
    private static final String ON_NOTIFICATION_POSTED = "onNotificationPosted";
    private static final String ON_NOTIFICATION_REMOVED = "onNotificationRemoved";
    private static final int CONCRETE_IN = 21;

    /** Constructs a new {@link OverrideConcreteDetector} */
    public OverrideConcreteDetector() {}

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

    @Nullable
    @Override
    public List<String> applicableSuperClasses() {
        return Collections.singletonList(NOTIFICATION_LISTENER_SERVICE_FQN);
    }

    @Override
    public void visitClass(@NonNull JavaContext context, @NonNull UClass declaration) {
        JavaEvaluator evaluator = context.getEvaluator();
        if (evaluator.isAbstract(declaration)) {
            return;
        }

        int minSdk = Math.max(context.getProject().getMinSdk(), getTargetApi(declaration));
        if (minSdk >= CONCRETE_IN) {
            return;
        }

        String[] methodNames = {ON_NOTIFICATION_POSTED, ON_NOTIFICATION_REMOVED};
        for (String methodName : methodNames) {
            boolean found = false;
            for (PsiMethod method : declaration.findMethodsByName(methodName, true)) {
                // Make sure it's not the base method, but that it's been defined
                // in a subclass, concretely
                PsiClass containingClass = method.getContainingClass();
                if (containingClass == null) {
                    continue;
                }
                if (NOTIFICATION_LISTENER_SERVICE_FQN.equals(containingClass.getQualifiedName())) {
                    continue;
                }
                // Make sure subclass isn't just defining another abstract definition
                // of the method
                if (evaluator.isAbstract(method)) {
                    continue;
                }
                // Make sure it has the exact right signature
                if (method.getParameterList().getParametersCount() != 1) {
                    continue; // Wrong signature
                }
                if (!evaluator.parameterHasType(method, 0, STATUS_BAR_NOTIFICATION_FQN)) {
                    continue;
                }

                found = true;
                break;
            }

            if (!found) {
                String message =
                        String.format(
                                "Must override `%1$s.%2$s(%3$s)`: Method was abstract until %4$d, and your `minSdkVersion` is %5$d",
                                NOTIFICATION_LISTENER_SERVICE_FQN,
                                methodName,
                                STATUS_BAR_NOTIFICATION_FQN,
                                CONCRETE_IN,
                                minSdk);
                context.report(ISSUE, declaration, context.getNameLocation(declaration), message);
                break;
            }
        }
    }

    private static int getTargetApi(@NonNull UClass node) {
        while (node != null) {
            int targetApi = ApiDetector.getTargetApi(node);
            if (targetApi != -1) {
                return targetApi;
            }

            node = UastUtils.getParentOfType(node, UClass.class, true);
        }

        return -1;
    }
}
