/*
 * Copyright 2000-2013 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.
 */
package com.intellij.codeInsight.daemon.impl;

import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInspection.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class RemoveSuppressWarningAction implements LocalQuickFix {
  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction");

  private final String myID;
  private final String myProblemLine;

  public RemoveSuppressWarningAction(final String ID, final String problemLine) {
    myID = ID;
    myProblemLine = problemLine;
  }

  public RemoveSuppressWarningAction(String id) {
    final int idx = id.indexOf(";");
    if (idx > -1) {
      myID = id.substring(0, idx);
      myProblemLine = id.substring(idx);
    }
    else {
      myID = id;
      myProblemLine = null;
    }
  }

  @Override
  @NotNull
  public String getFamilyName() {
    return QuickFixBundle.message("remove.suppression.action.family");
  }

  @Override
  public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
    PsiElement element = descriptor.getPsiElement();
    try {
      if (element instanceof PsiIdentifier) {
        if (!FileModificationService.getInstance().prepareFileForWrite(element.getContainingFile())) return;
        final PsiIdentifier identifier = (PsiIdentifier)element;
        final PsiDocCommentOwner commentOwner = PsiTreeUtil.getParentOfType(identifier, PsiDocCommentOwner.class);
        if (commentOwner != null) {
          final PsiElement psiElement = JavaSuppressionUtil.getElementMemberSuppressedIn(commentOwner, myID);
          if (psiElement instanceof PsiAnnotation) {
            removeFromAnnotation((PsiAnnotation)psiElement);
          } else if (psiElement instanceof PsiDocComment) {
            removeFromJavaDoc((PsiDocComment)psiElement);
          } else { //try to remove from all comments
            final Set<PsiComment> comments = new HashSet<PsiComment>();
            commentOwner.accept(new PsiRecursiveElementWalkingVisitor() {
              @Override public void visitComment(final PsiComment comment) {
                super.visitComment(comment);
                if (comment.getText().contains(myID)) {
                  comments.add(comment);
                }
              }
            });
            for (PsiComment comment : comments) {
              try {
                removeFromComment(comment, comments.size() > 1);
              }
              catch (IncorrectOperationException e) {
                LOG.error(e);
              }
            }
          }
        }
      }
    }
    catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }

  @Override
  @NotNull
  public String getName() {
    return QuickFixBundle.message("remove.suppression.action.name", myID);
  }

  private void removeFromComment(final PsiComment comment, final boolean checkLine) throws IncorrectOperationException {
    if (checkLine) {
      final PsiStatement statement = PsiTreeUtil.getNextSiblingOfType(comment, PsiStatement.class);
      if (statement != null && !Comparing.strEqual(statement.getText(), myProblemLine)) return;
    }
    String newText = removeFromElementText(comment);
    if (newText != null) {
      if (newText.isEmpty()) {
        comment.delete();
      }
      else {
        PsiComment newComment = JavaPsiFacade.getInstance(comment.getProject()).getElementFactory()
          .createCommentFromText("// " + SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME +" "+newText, comment);
        comment.replace(newComment);
      }
    }
  }

  private void removeFromJavaDoc(PsiDocComment docComment) throws IncorrectOperationException {
    PsiDocTag tag = docComment.findTagByName(SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME);
    if (tag == null) return;
    String newText = removeFromElementText(tag.getDataElements());
    if (newText != null && newText.isEmpty()) {
      tag.delete();
    }
    else if (newText != null) {
      newText = "@" + SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME + " " + newText;
      PsiDocTag newTag = JavaPsiFacade.getInstance(tag.getProject()).getElementFactory().createDocTagFromText(newText);
      tag.replace(newTag);
    }
  }

  @Nullable
  private String removeFromElementText(final PsiElement... elements) {
    String text = "";
    for (PsiElement element : elements) {
      text += StringUtil.trimStart(element.getText(), "//").trim();
    }
    text = StringUtil.trimStart(text, "@").trim();
    text = StringUtil.trimStart(text, SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME).trim();
    List<String> ids = StringUtil.split(text, ",");
    int i = ArrayUtil.find(ids.toArray(), myID);
    if (i==-1) return null;
    ids.remove(i);
    return StringUtil.join(ids, ",");
  }

  private void removeFromAnnotation(final PsiAnnotation annotation) throws IncorrectOperationException {
    PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
    for (PsiNameValuePair attribute : attributes) {
      PsiAnnotationMemberValue value = attribute.getValue();
      if (value instanceof PsiArrayInitializerMemberValue) {
        PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)value).getInitializers();
        for (PsiAnnotationMemberValue initializer : initializers) {
          if (removeFromValue(annotation, initializer, initializers.length==1)) return;
        }
      }
      if (removeFromValue(annotation, value, attributes.length==1)) return;
    }
  }

  private boolean removeFromValue(final PsiAnnotationMemberValue parent, final PsiAnnotationMemberValue value, final boolean removeParent) throws IncorrectOperationException {
    String text = value.getText();
    text = StringUtil.trimStart(text, "\"");
    text = StringUtil.trimEnd(text, "\"");
    if (myID.equals(text)) {
      if (removeParent) {
        parent.delete();
      }
      else {
        value.delete();
      }
      return true;
    }
    return false;
  }
}
