/*
 * Copyright 2010 Bas Leijdekkers
 *
 * 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.siyeh.ig.style;

import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

public class SimplifiableAnnotationInspection extends BaseInspection {

    @Nls
    @NotNull
    @Override
    public String getDisplayName() {
        return InspectionGadgetsBundle.message(
                "simplifiable.annotation.display.name");
    }

    @NotNull
    @Override
    protected String buildErrorString(Object... infos) {
        final String replacement = (String) infos[0];
        return InspectionGadgetsBundle.message(
                "simplifiable.annotation.problem.descriptor", replacement);
    }

    @Override
    protected InspectionGadgetsFix buildFix(Object... infos) {
        final String replacement = (String) infos[0];
        return new SimplifiableAnnotationFix(replacement);
    }

    private static class SimplifiableAnnotationFix
            extends InspectionGadgetsFix {

        private final String replacement;

        public SimplifiableAnnotationFix(String replacement) {
            super();
            this.replacement = replacement;
        }

        @NotNull
        public String getName() {
            return InspectionGadgetsBundle.message(
                    "simplifiable.annotation.quickfix");
        }

        @Override
        protected void doFix(Project project, ProblemDescriptor descriptor)
                throws IncorrectOperationException {
            final PsiElement element = descriptor.getPsiElement();
            if (!(element instanceof PsiAnnotation)) {
                return;
            }
            final PsiElementFactory factory =
                    JavaPsiFacade.getElementFactory(project);
            final PsiAnnotation annotation =
                    factory.createAnnotationFromText(replacement, element);
            element.replace(annotation);
        }
    }

    @Override
    public BaseInspectionVisitor buildVisitor() {
        return new SimplifiableAnnotationVisitor();
    }

    private static class SimplifiableAnnotationVisitor
            extends BaseInspectionVisitor {

        @Override
        public void visitAnnotation(PsiAnnotation annotation) {
            super.visitAnnotation(annotation);
            final PsiAnnotationParameterList parameterList =
                    annotation.getParameterList();
            final PsiJavaCodeReferenceElement nameReferenceElement =
                    annotation.getNameReferenceElement();
            if (nameReferenceElement == null) {
                return;
            }
            final PsiNameValuePair[] attributes = parameterList.getAttributes();

            final PsiElement[] annotationChildren = annotation.getChildren();
            if (annotationChildren.length >= 2) {
                final PsiElement child = annotationChildren[1];
                if (child instanceof PsiWhiteSpace) {
                    final String replacementText;
                    if (attributes.length > 0) {
                        replacementText = '@' + nameReferenceElement.getText() +
                                parameterList.getText();
                    } else {
                        replacementText = '@' + nameReferenceElement.getText();
                    }
                    registerError(annotation, replacementText);
                    return;
                }
            }
            if (attributes.length == 0) {
                final PsiElement[] children = parameterList.getChildren();
                if (children.length <= 0) {
                    return;
                }
                registerError(annotation, '@' + nameReferenceElement.getText());
            } else if (attributes.length == 1) {
                final PsiNameValuePair attribute = attributes[0];
                @NonNls final String name = attribute.getName();
                if (!"value".equals(name)) {
                    return;
                }
                registerError(annotation, '@' + nameReferenceElement.getText() +
                        '(' + attribute.getValue().getText() + ')');
            }
        }
    }
}

@@ -3605,17 +3605,16 @@
 utes();%0A
-%0A
         
@@ -3847,24 +3847,106 @@
 iteSpace) %7B%0A
+                    final String annotationName = nameReferenceElement.getText();%0A
             
@@ -4084,38 +4084,22 @@
 ' + 
-nameReferenceElement.getText()
+annotationName
  +%0A 
@@ -4235,38 +4235,22 @@
 ' + 
-nameReferenceElement.getText()
+annotationName
 ;%0A  
@@ -4612,38 +4612,37 @@
             
-registerError(
+final String 
 annotation, 
@@ -4631,39 +4631,38 @@
 tring annotation
-, '@' +
+Name =
  nameReferenceEl
@@ -4676,16 +4676,80 @@
 etText()
+;%0A                registerError(annotation, '@' + annotationName
 );%0A     
@@ -5026,38 +5026,239 @@
             
-registerError(
+final PsiAnnotationMemberValue attributeValue =%0A                        attribute.getValue();%0A                if (attributeValue == null) %7B%0A                    return;%0A                %7D%0A                final String 
 annotation, 
@@ -5255,23 +5255,22 @@
 notation
-, '@' +
+Name =
  nameRef
@@ -5292,16 +5292,85 @@
 etText()
+;%0A                final String replacementText = '@' + annotationName
  +%0A     
@@ -5403,27 +5403,21 @@
 ttribute
-.get
 Value
-()
 .getText
@@ -5424,16 +5424,75 @@
 () + ')'
+;%0A                registerError(annotation, replacementText
 );%0A     

fix NPE