/*
 * 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 static com.android.tools.lint.detector.api.Lint.getMethodName;

import com.android.annotations.NonNull;
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.PsiMethod;
import java.util.Collections;
import java.util.List;
import org.jetbrains.uast.UBlockExpression;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.ULambdaExpression;
import org.jetbrains.uast.ULiteralExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.UReturnExpression;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;

/** Detector looking for Toast.makeText() without a corresponding show() call */
public class ToastDetector extends Detector implements SourceCodeScanner {
    /** The main issue discovered by this detector */
    public static final Issue ISSUE =
            Issue.create(
                            "ShowToast",
                            "Toast created but not shown",
                            "`Toast.makeText()` creates a `Toast` but does **not** show it. You must call "
                                    + "`show()` on the resulting object to actually make the `Toast` appear.",
                            Category.CORRECTNESS,
                            6,
                            Severity.WARNING,
                            new Implementation(ToastDetector.class, Scope.JAVA_FILE_SCOPE))
                    .setAndroidSpecific(true);

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

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

    @Override
    public List<String> getApplicableMethodNames() {
        return Collections.singletonList("makeText");
    }

    @Override
    public void visitMethodCall(
            @NonNull JavaContext context,
            @NonNull UCallExpression call,
            @NonNull PsiMethod method) {
        if (!context.getEvaluator().isMemberInClass(method, "android.widget.Toast")) {
            return;
        }

        // Make sure you pass the right kind of duration: it's not a delay, it's
        //  LENGTH_SHORT or LENGTH_LONG
        // (see http://code.google.com/p/android/issues/detail?id=3655)
        List<UExpression> args = call.getValueArguments();
        if (args.size() == 3) {
            UExpression duration = args.get(2);
            if (duration instanceof ULiteralExpression) {
                context.report(
                        ISSUE,
                        duration,
                        context.getLocation(duration),
                        "Expected duration `Toast.LENGTH_SHORT` or `Toast.LENGTH_LONG`, a custom "
                                + "duration value is not supported");
            }
        }

        @SuppressWarnings("unchecked")
        UElement surroundingDeclaration =
                UastUtils.getParentOfType(
                        call, true, UMethod.class, UBlockExpression.class, ULambdaExpression.class);

        if (surroundingDeclaration == null) {
            return;
        }

        UElement parent = call.getUastParent();
        if (parent instanceof UMethod
                || parent instanceof UReferenceExpression
                        && parent.getUastParent() instanceof UMethod) {
            // Kotlin expression body
            return;
        }

        ShowFinder finder = new ShowFinder(call);
        surroundingDeclaration.accept(finder);
        if (!finder.isShowCalled()) {
            context.report(
                    ISSUE,
                    call,
                    context.getCallLocation(call, true, false),
                    "Toast created but not shown: did you forget to call `show()` ?");
        }
    }

    private static class ShowFinder extends AbstractUastVisitor {
        /** The target makeText call */
        private final UCallExpression target;
        /** Whether we've found the show method */
        private boolean found;
        /** Whether we've seen the target makeText node yet */
        private boolean seenTarget;

        private ShowFinder(UCallExpression target) {
            this.target = target;
        }

        @Override
        public boolean visitCallExpression(UCallExpression node) {
            if (node == target
                    ||
                    //noinspection LintDetectorImpl
                    node.getSourcePsi() != null && node.getSourcePsi() == target.getPsi()) {
                seenTarget = true;
            } else {
                if ((seenTarget || target.equals(node.getReceiver()))
                        && "show".equals(getMethodName(node))) {
                    // TODO: Do more flow analysis to see whether we're really calling show
                    // on the right type of object?
                    found = true;
                }
            }
            return super.visitCallExpression(node);
        }

        @Override
        public boolean visitReturnExpression(UReturnExpression node) {
            if (UastUtils.isUastChildOf(target, node.getReturnExpression(), true)) {
                // If you just do "return Toast.makeText(...) don't warn
                found = true;
            }
            return super.visitReturnExpression(node);
        }

        boolean isShowCalled() {
            return found;
        }
    }
}
