// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.

package com.intellij.codeInsight.daemon.impl.analysis;

import com.intellij.codeInsight.daemon.XmlErrorMessages;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author spleaner
 */
public class RemoveAttributeIntentionFix implements LocalQuickFix, IntentionAction {
  private final String myLocalName;

  /**
   * To be removed in 2018.3
   */
  @Deprecated
  public RemoveAttributeIntentionFix(final String localName, XmlAttribute attribute) {
    this(localName);
  }

  public RemoveAttributeIntentionFix(final String localName) {
    myLocalName = localName;
  }

  @SuppressWarnings("unused") // to instantiate via extension
  public RemoveAttributeIntentionFix() {
    this(null);
  }

  @Override
  @NotNull
  public String getName() {
    return XmlErrorMessages.message("remove.attribute.quickfix.text", myLocalName);
  }

  @Nls(capitalization = Nls.Capitalization.Sentence)
  @NotNull
  @Override
  public String getText() {
    return myLocalName != null? getName() : getFamilyName();
  }

  @Override
  @NotNull
  public String getFamilyName() {
    return XmlErrorMessages.message("remove.attribute.quickfix.family");
  }

  @Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    return getAttribute(editor, file) != null;
  }

  @Override
  public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
    removeAttribute(getAttribute(editor, file), editor);
  }

  @Override
  public boolean startInWriteAction() {
    return true;
  }

  @Override
  public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
    PsiElement e = descriptor.getPsiElement();
    removeAttribute(e, null);
  }

  protected void removeAttribute(PsiElement e, Editor editor) {
    final XmlAttribute myAttribute = PsiTreeUtil.getParentOfType(e, XmlAttribute.class, false);
    if (myAttribute == null) return;

    PsiElement next = findNextAttribute(myAttribute);
    myAttribute.delete();

    if (next != null && editor != null) {
      editor.getCaretModel().moveToOffset(next.getTextRange().getStartOffset());
    }
  }

  @Nullable
  private static PsiElement findNextAttribute(final XmlAttribute attribute) {
    PsiElement nextSibling = attribute.getNextSibling();
    while (nextSibling != null) {
      if (nextSibling instanceof XmlAttribute) return nextSibling;
      nextSibling =  nextSibling.getNextSibling();
    }
    return null;
  }

  private static XmlAttribute getAttribute(Editor editor, PsiFile file) {
    int offset = editor.getCaretModel().getOffset();
    FileViewProvider provider = file.getViewProvider();
    for (Language language : provider.getLanguages()) {
      PsiElement element = provider.findElementAt(offset, language);
      XmlAttribute attribute = PsiTreeUtil.getParentOfType(element, XmlAttribute.class);
      if (attribute != null) {
        return attribute;
      }
      element = provider.findElementAt(offset - 1, language);
      attribute = PsiTreeUtil.getParentOfType(element, XmlAttribute.class);
      if (attribute != null) {
        return attribute;
      }
    }
    return null;
  }
}

@@ -415,43 +415,8 @@
 or;%0A
-import com.intellij.lang.Language;%0A
 impo
@@ -503,50 +503,8 @@
 ct;%0A
-import com.intellij.psi.FileViewProvider;%0A
 impo
@@ -3292,191 +3292,8 @@
 ();%0A
-    FileViewProvider provider = file.getViewProvider();%0A    for (Language language : provider.getLanguages()) %7B%0A      PsiElement element = provider.findElementAt(offset, language);%0A  
     
@@ -3337,39 +3337,58 @@
 getParentOfType(
-element
+file.findElementAt(offset)
 , XmlAttribute.c
@@ -3386,34 +3386,32 @@
 tribute.class);%0A
-  
     if (attribut
@@ -3404,33 +3404,33 @@
   if (attribute 
-!
+=
 = null) %7B%0A      
@@ -3433,260 +3433,127 @@
     
-  return attribute;%0A      %7D%0A      element = provider.findElementAt(offset - 1, language);%0A      attribute = PsiTreeUtil.getParentOfType(element, XmlAttribute.class);%0A      if (attribute != null) %7B%0A        return attribute;%0A      %7D%0A    %7D%0A    return null
+attribute = PsiTreeUtil.getParentOfType(file.findElementAt(offset - 1), XmlAttribute.class);%0A    %7D%0A    return attribute
 ;%0A  

disable invoking "remove attribute" intention invocation from outer language