/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.ide.eclipse.adt.internal.lint;

import static com.android.SdkConstants.FQCN_SUPPRESS_LINT;
import static com.android.SdkConstants.FQCN_TARGET_API;
import static com.android.SdkConstants.SUPPRESS_LINT;
import static com.android.SdkConstants.TARGET_API;
import static org.eclipse.jdt.core.dom.ArrayInitializer.EXPRESSIONS_PROPERTY;
import static org.eclipse.jdt.core.dom.SingleMemberAnnotation.VALUE_PROPERTY;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.sdklib.SdkVersionInfo;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.tools.lint.checks.AnnotationDetector;
import com.android.tools.lint.checks.ApiDetector;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.Scope;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.ui.IWorkingCopyManager;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.graphics.Image;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IMarkerResolution;
import org.eclipse.ui.IMarkerResolution2;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Marker resolution for adding {@code @SuppressLint} annotations in Java files.
 * It can also add {@code @TargetApi} annotations.
 */
class AddSuppressAnnotation implements IMarkerResolution2 {
    private final IMarker mMarker;
    private final String mId;
    private final BodyDeclaration mNode;
    private final String mDescription;
    /**
     * Should it create a {@code @TargetApi} annotation instead of
     * {@code SuppressLint} ? If so pass a non null API level
     */
    private final String mTargetApi;

    private AddSuppressAnnotation(
            @NonNull String id,
            @NonNull IMarker marker,
            @NonNull BodyDeclaration node,
            @NonNull String description,
            @Nullable String targetApi) {
        mId = id;
        mMarker = marker;
        mNode = node;
        mDescription = description;
        mTargetApi = targetApi;
    }

    @Override
    public String getLabel() {
        return mDescription;
    }

    @Override
    public String getDescription() {
        return null;
    }

    @Override
    public Image getImage() {
        return IconFactory.getInstance().getIcon("newannotation"); //$NON-NLS-1$
    }

    @Override
    public void run(IMarker marker) {
        ITextEditor textEditor = AdtUtils.getActiveTextEditor();
        IDocumentProvider provider = textEditor.getDocumentProvider();
        IEditorInput editorInput = textEditor.getEditorInput();
        IDocument document = provider.getDocument(editorInput);
        if (document == null) {
            return;
        }
        IWorkingCopyManager manager = JavaUI.getWorkingCopyManager();
        ICompilationUnit compilationUnit = manager.getWorkingCopy(editorInput);
        try {
            MultiTextEdit edit;
            if (mTargetApi == null) {
                edit = addSuppressAnnotation(document, compilationUnit, mNode);
            } else {
                edit = addTargetApiAnnotation(document, compilationUnit, mNode);
            }
            if (edit != null) {
                edit.apply(document);

                // Remove the marker now that the suppress annotation has been added
                // (so the user doesn't have to re-run lint just to see it disappear,
                // and besides we don't want to keep offering marker resolutions on this
                // marker which could lead to duplicate annotations since the above code
                // assumes that the current id isn't in the list of values, since otherwise
                // lint shouldn't have complained here.
                mMarker.delete();
            }
        } catch (Exception ex) {
            AdtPlugin.log(ex, "Could not add suppress annotation");
        }
    }

    @SuppressWarnings({"rawtypes"}) // Java AST API has raw types
    private MultiTextEdit addSuppressAnnotation(
            IDocument document,
            ICompilationUnit compilationUnit,
            BodyDeclaration declaration) throws CoreException {
        List modifiers = declaration.modifiers();
        SingleMemberAnnotation existing = null;
        for (Object o : modifiers) {
            if (o instanceof SingleMemberAnnotation) {
                SingleMemberAnnotation annotation = (SingleMemberAnnotation) o;
                String type = annotation.getTypeName().getFullyQualifiedName();
                if (type.equals(FQCN_SUPPRESS_LINT) || type.endsWith(SUPPRESS_LINT)) {
                    existing = annotation;
                    break;
                }
            }
        }

        ImportRewrite importRewrite = ImportRewrite.create(compilationUnit, true);
        String local = importRewrite.addImport(FQCN_SUPPRESS_LINT);
        AST ast = declaration.getAST();
        ASTRewrite rewriter = ASTRewrite.create(ast);
        if (existing == null) {
            SingleMemberAnnotation newAnnotation = ast.newSingleMemberAnnotation();
            newAnnotation.setTypeName(ast.newSimpleName(local));
            StringLiteral value = ast.newStringLiteral();
            value.setLiteralValue(mId);
            newAnnotation.setValue(value);
            ListRewrite listRewrite = rewriter.getListRewrite(declaration,
                    declaration.getModifiersProperty());
            listRewrite.insertFirst(newAnnotation, null);
        } else {
            Expression existingValue = existing.getValue();
            if (existingValue instanceof StringLiteral) {
                StringLiteral stringLiteral = (StringLiteral) existingValue;
                if (mId.equals(stringLiteral.getLiteralValue())) {
                    // Already contains the id
                    return null;
                }
                // Create a new array initializer holding the old string plus the new id
                ArrayInitializer array = ast.newArrayInitializer();
                StringLiteral old = ast.newStringLiteral();
                old.setLiteralValue(stringLiteral.getLiteralValue());
                array.expressions().add(old);
                StringLiteral value = ast.newStringLiteral();
                value.setLiteralValue(mId);
                array.expressions().add(value);
                rewriter.set(existing, VALUE_PROPERTY, array, null);
            } else if (existingValue instanceof ArrayInitializer) {
                // Existing array: just append the new string
                ArrayInitializer array = (ArrayInitializer) existingValue;
                List expressions = array.expressions();
                if (expressions != null) {
                    for (Object o : expressions) {
                        if (o instanceof StringLiteral) {
                            if (mId.equals(((StringLiteral)o).getLiteralValue())) {
                                // Already contains the id
                                return null;
                            }
                        }
                    }
                }
                StringLiteral value = ast.newStringLiteral();
                value.setLiteralValue(mId);
                ListRewrite listRewrite = rewriter.getListRewrite(array, EXPRESSIONS_PROPERTY);
                listRewrite.insertLast(value, null);
            } else {
                assert false : existingValue;
                return null;
            }
        }

        TextEdit importEdits = importRewrite.rewriteImports(new NullProgressMonitor());
        TextEdit annotationEdits = rewriter.rewriteAST(document, null);

        // Apply to the document
        MultiTextEdit edit = new MultiTextEdit();
        // Create the edit to change the imports, only if
        // anything changed
        if (importEdits.hasChildren()) {
            edit.addChild(importEdits);
        }
        edit.addChild(annotationEdits);

        return edit;
    }

    @SuppressWarnings({"rawtypes"}) // Java AST API has raw types
    private MultiTextEdit addTargetApiAnnotation(
            IDocument document,
            ICompilationUnit compilationUnit,
            BodyDeclaration declaration) throws CoreException {
        List modifiers = declaration.modifiers();
        SingleMemberAnnotation existing = null;
        for (Object o : modifiers) {
            if (o instanceof SingleMemberAnnotation) {
                SingleMemberAnnotation annotation = (SingleMemberAnnotation) o;
                String type = annotation.getTypeName().getFullyQualifiedName();
                if (type.equals(FQCN_TARGET_API) || type.endsWith(TARGET_API)) {
                    existing = annotation;
                    break;
                }
            }
        }

        ImportRewrite importRewrite = ImportRewrite.create(compilationUnit, true);
        importRewrite.addImport("android.os.Build"); //$NON-NLS-1$
        String local = importRewrite.addImport(FQCN_TARGET_API);
        AST ast = declaration.getAST();
        ASTRewrite rewriter = ASTRewrite.create(ast);
        if (existing == null) {
            SingleMemberAnnotation newAnnotation = ast.newSingleMemberAnnotation();
            newAnnotation.setTypeName(ast.newSimpleName(local));
            Expression value = createLiteral(ast);
            newAnnotation.setValue(value);
            ListRewrite listRewrite = rewriter.getListRewrite(declaration,
                    declaration.getModifiersProperty());
            listRewrite.insertFirst(newAnnotation, null);
        } else {
            Expression value = createLiteral(ast);
            rewriter.set(existing, VALUE_PROPERTY, value, null);
        }

        TextEdit importEdits = importRewrite.rewriteImports(new NullProgressMonitor());
        TextEdit annotationEdits = rewriter.rewriteAST(document, null);
        MultiTextEdit edit = new MultiTextEdit();
        if (importEdits.hasChildren()) {
            edit.addChild(importEdits);
        }
        edit.addChild(annotationEdits);

        return edit;
    }

    private Expression createLiteral(AST ast) {
        Expression value;
        if (!isCodeName()) {
            value = ast.newQualifiedName(
                    ast.newQualifiedName(ast.newSimpleName("Build"), //$NON-NLS-1$
                                ast.newSimpleName("VERSION_CODES")), //$NON-NLS-1$
                    ast.newSimpleName(mTargetApi));
        } else {
            value = ast.newNumberLiteral(mTargetApi);
        }
        return value;
    }

    private boolean isCodeName() {
        return Character.isDigit(mTargetApi.charAt(0));
    }

    /**
     * Adds any applicable suppress lint fix resolutions into the given list
     *
     * @param marker the marker to create fixes for
     * @param id the issue id
     * @param resolutions a list to add the created resolutions into, if any
     */
    public static void createFixes(IMarker marker, String id,
            List<IMarkerResolution> resolutions) {
        ITextEditor textEditor = AdtUtils.getActiveTextEditor();
        IDocumentProvider provider = textEditor.getDocumentProvider();
        IEditorInput editorInput = textEditor.getEditorInput();
        IDocument document = provider.getDocument(editorInput);
        if (document == null) {
            return;
        }

        IWorkingCopyManager manager = JavaUI.getWorkingCopyManager();
        ICompilationUnit compilationUnit = manager.getWorkingCopy(editorInput);
        int offset = 0;
        int length = 0;
        int start = marker.getAttribute(IMarker.CHAR_START, -1);
        int end = marker.getAttribute(IMarker.CHAR_END, -1);
        offset = start;
        length = end - start;
        CompilationUnit root = SharedASTProvider.getAST(compilationUnit,
                SharedASTProvider.WAIT_YES, null);
        if (root == null) {
            return;
        }

        int api = -1;
        if (id.equals(ApiDetector.UNSUPPORTED.getId()) ||
                id.equals(ApiDetector.INLINED.getId())) {
            String message = marker.getAttribute(IMarker.MESSAGE, null);
            if (message != null) {
                Pattern pattern = Pattern.compile("\\s(\\d+)\\s"); //$NON-NLS-1$
                Matcher matcher = pattern.matcher(message);
                if (matcher.find()) {
                    api = Integer.parseInt(matcher.group(1));
                }
            }
        }

        Issue issue = EclipseLintClient.getRegistry().getIssue(id);
        boolean isClassDetector = issue != null && issue.getImplementation().getScope().contains(
                Scope.CLASS_FILE);

        // Don't offer to suppress (with an annotation) the annotation checks
        if (issue == AnnotationDetector.ISSUE) {
            return;
        }

        NodeFinder nodeFinder = new NodeFinder(root, offset, length);
        ASTNode coveringNode;
        if (offset <= 0) {
            // Error added on the first line of a Java class: typically from a class-based
            // detector which lacks line information. Map this to the top level class
            // in the file instead.
            coveringNode = root;
            if (root.types() != null && root.types().size() > 0) {
                Object type = root.types().get(0);
                if (type instanceof ASTNode) {
                    coveringNode = (ASTNode) type;
                }
            }
        } else {
            coveringNode = nodeFinder.getCoveringNode();
        }
        for (ASTNode body = coveringNode; body != null; body = body.getParent()) {
            if (body instanceof BodyDeclaration) {
                BodyDeclaration declaration = (BodyDeclaration) body;

                String target = null;
                if (body instanceof MethodDeclaration) {
                    target = ((MethodDeclaration) body).getName().toString() + "()"; //$NON-NLS-1$
                } else if (body instanceof FieldDeclaration) {
                    target = "field";
                    FieldDeclaration field = (FieldDeclaration) body;
                    if (field.fragments() != null && field.fragments().size() > 0) {
                        ASTNode first = (ASTNode) field.fragments().get(0);
                        if (first instanceof VariableDeclarationFragment) {
                            VariableDeclarationFragment decl = (VariableDeclarationFragment) first;
                            target = decl.getName().toString();
                        }
                    }
                } else if (body instanceof AnonymousClassDeclaration) {
                    target = "anonymous class";
                } else if (body instanceof TypeDeclaration) {
                    target = ((TypeDeclaration) body).getName().toString();
                } else {
                    target = body.getClass().getSimpleName();
                }

                // In class files, detectors can only find annotations on methods
                // and on classes, not on variable declarations
                if (isClassDetector && !(body instanceof MethodDeclaration
                            || body instanceof TypeDeclaration
                            || body instanceof AnonymousClassDeclaration
                            || body instanceof FieldDeclaration)) {
                    continue;
                }

                String desc = String.format("Add @SuppressLint '%1$s\' to '%2$s'", id, target);
                resolutions.add(new AddSuppressAnnotation(id, marker, declaration, desc, null));

                if (api != -1
                        // @TargetApi is only valid on methods and classes, not fields etc
                        && (body instanceof MethodDeclaration
                                || body instanceof TypeDeclaration)) {
                    String apiString = SdkVersionInfo.getBuildCode(api);
                    if (apiString == null) {
                        apiString = Integer.toString(api);
                    }
                    desc = String.format("Add @TargetApi(%1$s) to '%2$s'", apiString, target);
                    resolutions.add(new AddSuppressAnnotation(id, marker, declaration, desc,
                            apiString));
                }
            }
        }
    }
}
