package de.plushnikov.intellij.plugin.processor.clazz.fieldnameconstants;

import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import de.plushnikov.intellij.plugin.lombokconfig.ConfigDiscovery;
import de.plushnikov.intellij.plugin.problem.ProblemBuilder;
import de.plushnikov.intellij.plugin.problem.ProblemEmptyBuilder;
import de.plushnikov.intellij.plugin.processor.handler.FieldNameConstantsHandler;
import de.plushnikov.intellij.plugin.util.PsiAnnotationSearchUtil;
import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil;
import lombok.experimental.FieldNameConstants;
import org.jetbrains.annotations.NotNull;

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

/**
 * Updates fields of existing inner class type in class annotated by FieldNameConstants
 *
 * @author alanachtenberg
 */
public class FieldNameConstantsPredefinedInnerClassFieldProcessor extends AbstractFieldNameConstantsProcessor {

  public FieldNameConstantsPredefinedInnerClassFieldProcessor(@NotNull ConfigDiscovery configDiscovery) {
    super(configDiscovery, PsiField.class, FieldNameConstants.class);
  }

  @NotNull
  @Override
  public List<? super PsiElement> process(@NotNull PsiClass psiClass) {
    if (psiClass.getParent() instanceof PsiClass) {
      PsiClass parentClass = (PsiClass) psiClass.getParent();
      PsiAnnotation psiAnnotation = PsiAnnotationSearchUtil.findAnnotation(parentClass, getSupportedAnnotationClasses());
      if (null != psiAnnotation) {
        ProblemEmptyBuilder problemBuilder = ProblemEmptyBuilder.getInstance();
        if (super.validate(psiAnnotation, parentClass, problemBuilder)) {
          final String typeName = FieldNameConstantsHandler.getTypeName(parentClass, psiAnnotation);
          if (typeName.equals(psiClass.getName())) {
            if (validate(psiAnnotation, psiClass, problemBuilder)) {
              List<? super PsiElement> result = new ArrayList<>();
              generatePsiElements(parentClass, psiClass, psiAnnotation, result);
              return result;
            }
          }
        }
      }
    }
    return Collections.emptyList();
  }

  @Override
  protected boolean validate(@NotNull PsiAnnotation psiAnnotation, @NotNull PsiClass psiClass, @NotNull ProblemBuilder builder) {
    final boolean asEnum = PsiAnnotationUtil.getBooleanAnnotationValue(psiAnnotation, "asEnum", false);
    if (psiClass.isEnum() != asEnum) {
      builder.addError("@FieldNameConstants inner type already exists, but asEnum=" + asEnum + " does not match existing type");
      return false;
    }
    return true;
  }

  @Override
  protected void generatePsiElements(@NotNull PsiClass psiClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target) {
    //do nothing
  }

  private void generatePsiElements(@NotNull PsiClass psiClass, @NotNull PsiClass existingInnerClass, @NotNull PsiAnnotation psiAnnotation, @NotNull List<? super PsiElement> target) {
    final Collection<PsiField> psiFields = filterFields(psiClass, psiAnnotation);
    if (!psiFields.isEmpty()) {
      List<PsiField> newFields = FieldNameConstantsHandler.createFields(existingInnerClass, psiFields);
      target.addAll(newFields);
    }
  }
}

@@ -611,24 +611,80 @@
 tationUtil;%0A
+import de.plushnikov.intellij.plugin.util.PsiClassUtil;%0A
 import lombo
@@ -718,16 +718,16 @@
 stants;%0A
-
 import o
@@ -870,16 +870,43 @@
 il.List;
+%0Aimport java.util.Optional;
 %0A%0A/**%0A *
@@ -2033,18 +2033,21 @@
 ation, p
-si
+arent
 Class, p
@@ -2470,24 +2470,248 @@
  builder) %7B%0A
+    final String typeName = FieldNameConstantsHandler.getTypeName(psiClass, psiAnnotation);%0A    Optional%3CPsiClass%3E innerClass = PsiClassUtil.getInnerClassInternByName(psiClass, typeName);%0A    if (innerClass.isPresent()) %7B%0A  
     final bo
@@ -2806,29 +2806,39 @@
 e);%0A    
+  
 if (
-psi
+inner
 Class.
+get().
 isEnum()
@@ -2847,24 +2847,26 @@
 = asEnum) %7B%0A
+  
       builde
@@ -2984,24 +2984,26 @@
 pe%22);%0A      
+  
 return false
@@ -3004,16 +3004,24 @@
  false;%0A
+      %7D%0A
     %7D%0A  

revert my wrong changes