/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * 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.
 */

/*
 * User: anna
 * Date: 29-Dec-2008
 */
package com.intellij.codeInsight.highlighting;

import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
import com.intellij.codeInspection.InspectionProfile;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.reference.RefManagerImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBase<PsiLiteralExpression> {
  private static final Logger LOG = Logger.getInstance("#" + HighlightSuppressedWarningsHandler.class.getName());

  private final PsiAnnotation myTarget;
  private final PsiLiteralExpression mySuppressedExpression;

  protected HighlightSuppressedWarningsHandler(Editor editor, PsiFile file, PsiAnnotation target, PsiLiteralExpression suppressedExpression) {
    super(editor, file);
    myTarget = target;
    mySuppressedExpression = suppressedExpression;
  }

  public List<PsiLiteralExpression> getTargets() {
    final List<PsiLiteralExpression> result = new ArrayList<PsiLiteralExpression>();
    if (mySuppressedExpression != null) {
      result.add(mySuppressedExpression);
      return result;
    }
    final PsiAnnotationParameterList list = myTarget.getParameterList();
    final PsiNameValuePair[] attributes = list.getAttributes();
    for (PsiNameValuePair attribute : attributes) {
      final PsiAnnotationMemberValue value = attribute.getValue();
      if (value instanceof PsiArrayInitializerMemberValue) {
        final PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)value).getInitializers();
        for (PsiAnnotationMemberValue initializer : initializers) {
          if (initializer instanceof PsiLiteralExpression) {
            result.add((PsiLiteralExpression)initializer);
          }
        }
      }
    }
    return result;
  }

  protected void selectTargets(List<PsiLiteralExpression> targets, final Consumer<List<PsiLiteralExpression>> selectionConsumer) {
    if (targets.size() == 1) {
      selectionConsumer.consume(targets);
    } else {
      JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<PsiLiteralExpression>("Choose Inspections to Highlight Suppressed Problems from", targets){
        @Override
        public PopupStep onChosen(PsiLiteralExpression selectedValue, boolean finalChoice) {
          selectionConsumer.consume(Collections.singletonList(selectedValue));
          return FINAL_CHOICE;
        }

        @NotNull
        @Override
        public String getTextFor(PsiLiteralExpression value) {
          final Object o = value.getValue();
          LOG.assertTrue(o instanceof String);
          return (String)o;
        }
      }).showInBestPositionFor(myEditor);
    }
  }

  public void computeUsages(List<PsiLiteralExpression> targets) {
    final Project project = myTarget.getProject();
    final PsiElement parent = myTarget.getParent().getParent();
    LocalInspectionsPass pass = new LocalInspectionsPass(myFile, myFile.getViewProvider().getDocument(), parent.getTextRange().getStartOffset(), parent.getTextRange().getEndOffset());
    final InspectionProfile inspectionProfile =
      InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
    for (PsiLiteralExpression target : targets) {
      final Object value = target.getValue();
      if (value instanceof String) {
        final InspectionProfileEntry toolById = ((InspectionProfileImpl)inspectionProfile).getToolById(((String)value), target);
        if (toolById instanceof LocalInspectionToolWrapper) {
          final LocalInspectionToolWrapper tool = new LocalInspectionToolWrapper(((LocalInspectionToolWrapper)toolById).getTool());
          final InspectionManagerEx managerEx = ((InspectionManagerEx)InspectionManagerEx.getInstance(project));
          final GlobalInspectionContextImpl context = managerEx.createNewGlobalContext(false);
          tool.initialize(context);
          ((RefManagerImpl)context.getRefManager()).inspectionReadActionStarted();
          pass.doInspectInBatch(managerEx, Collections.<InspectionProfileEntry>singletonList(tool), false);
          for (HighlightInfo info : pass.getInfos()) {
            final PsiElement element = CollectHighlightsUtil.findCommonParent(myFile, info.startOffset, info.endOffset);
            if (element != null) {
              addOccurrence(element);
            }
          }
        }
      }
    }
  }
}

@@ -1394,16 +1394,169 @@
 Editor;%0A
+import com.intellij.openapi.progress.ProgressIndicator;%0Aimport com.intellij.openapi.progress.ProgressManager;%0Aimport com.intellij.openapi.progress.Task;%0A
 import c
@@ -4595,16 +4595,22 @@
 ();%0A    
+final 
 LocalIns
@@ -5691,24 +5691,223 @@
 nStarted();%0A
+          ProgressManager.getInstance().run(new Task.Modal(project, %22Collecting information...%22, true) %7B%0A            @Override%0A            public void run(@NotNull ProgressIndicator indicator) %7B%0A    
           pa
@@ -5994,32 +5994,111 @@
 (tool), false);%0A
+            %7D%0A%0A            @Override%0A            public void onSuccess() %7B%0A    
           for (H
@@ -6132,24 +6132,28 @@
 tInfos()) %7B%0A
+    
             
@@ -6269,24 +6269,28 @@
             
+  
+  
 if (element 
@@ -6296,24 +6296,28 @@
  != null) %7B%0A
+    
             
@@ -6338,24 +6338,58 @@
 e(element);%0A
+                %7D%0A              %7D%0A
             
@@ -6382,32 +6382,32 @@
 %7D%0A            %7D%0A
-
           %7D%0A    
@@ -6393,32 +6393,34 @@
    %7D%0A          %7D
+);
 %0A        %7D%0A     

use progress for inspections (EA-19608 )