package org.asciidoc.intellij.quickfix;

import com.intellij.ide.actions.OpenFileAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import org.asciidoc.intellij.psi.AsciiDocBlockMacro;
import org.asciidoc.intellij.psi.AsciiDocFileReference;

/**
 * @author Alexander Schwartz 2019
 */
public interface AsciiDocCreateMissingFile {

  default void applyFix(PsiElement element, Project project) {
    PsiDirectory parent = element.getContainingFile().getParent();
    if (parent == null) {
      return;
    }
    for (PsiReference r : element.getReferences()) {
      if (r instanceof AsciiDocFileReference) {
        AsciiDocFileReference adr = (AsciiDocFileReference) r;
        PsiElement resolved = r.resolve();
        if (resolved instanceof PsiDirectory) {
          parent = (PsiDirectory) resolved;
        } else if (resolved == null) {
          if (adr.canBeCreated(parent)) {
            PsiElement e = adr.createFileOrFolder(parent);
            if (e instanceof PsiDirectory) {
              parent = (PsiDirectory) e;
            } else {
              ApplicationManager.getApplication().invokeLater(() -> OpenFileAction.openFile(((PsiFile) e).getVirtualFile(), project));
              break;
            }
          }
        }
      }
    }
  }

  static boolean isAvailable(PsiElement element) {
    boolean isAvailable = false;
    if (element instanceof AsciiDocBlockMacro) {
      // this will create empty files, doesn't make sense for images
      if (((AsciiDocBlockMacro) element).getMacroName().equals("image")) {
        return false;
      }
    }
    PsiFile containingFile = element.getContainingFile();
    if (containingFile != null) {
      PsiDirectory parent = containingFile.getParent();
      if (parent != null) {
        for (PsiReference r : element.getReferences()) {
          if (r instanceof AsciiDocFileReference) {
            AsciiDocFileReference adr = (AsciiDocFileReference) r;
            PsiElement resolved = r.resolve();
            if (resolved instanceof PsiDirectory) {
              parent = (PsiDirectory) resolved;
            } else if (resolved == null) {
              if (adr.canBeCreated(parent)) {
                isAvailable = true;
                break;
              }
            }
          }
        }
      }
    }
    return isAvailable;
  }

}

@@ -442,16 +442,49 @@
 rence;%0A%0A
+import java.util.regex.Pattern;%0A%0A
 /**%0A * @
@@ -1577,24 +1577,82 @@
 le = false;%0A
+    PsiFile containingFile = element.getContainingFile();%0A
     if (elem
@@ -1750,16 +1750,20 @@
 nse for 
+all 
 images%0A 
@@ -1848,62 +1848,109 @@
     
-return false;%0A      %7D%0A    %7D%0A    PsiFile containingF
+// in case of image macro with a draw.io image, create empty file makes sense%0A        String f
 ile
+Name
  = e
@@ -1959,33 +1959,226 @@
 ment.get
-ContainingFile();
+FirstChild().getNextSibling().getText();%0A        boolean isDrawioFile = Pattern.matches(%22%5E.*%5B.%5D(drawio%7Cdio)%5B.%5D(svg%7Cpng)$%22, fileName);%0A        if (!isDrawioFile) %7B%0A          return false;%0A        %7D%0A      %7D%0A    %7D
 %0A    if 

create missing file inspection for drawio (#575)