package xyz.upperlevel.uppercore.util.nms.impl.entity;

import org.bukkit.entity.Entity;
import xyz.upperlevel.uppercore.util.nms.NmsPacket;
import xyz.upperlevel.uppercore.util.nms.exceptions.UnsupportedVersionException;
import xyz.upperlevel.uppercore.util.nms.impl.TagNms;

import java.lang.reflect.Method;
import java.util.function.Consumer;

import static xyz.upperlevel.uppercore.util.nms.Nms.handleException;

public final class EntityNms {
    public static final Class<?> NMS_CLASS;
    public static final Class<?> BUKKIT_CLASS;
    private static final Method getHandle;
    private static final Method entityGetTag;
    private static final Method entitySetTag;

   static {
       try {
           NMS_CLASS = NmsPacket.NMS.getClass("Entity");
           BUKKIT_CLASS = NmsPacket.CRAFT_ENTITY.getClass("CraftEntity");


           getHandle = BUKKIT_CLASS.getDeclaredMethod("getHandle");
           entityGetTag = NMS_CLASS.getDeclaredMethod("c", TagNms.CLASS);
           entitySetTag = NMS_CLASS.getDeclaredMethod("f", TagNms.CLASS);
       } catch (Exception e) {
           throw new UnsupportedVersionException(e);
       }
   }

   public static Object getHandle(Entity entity) {
       try {
           return getHandle.invoke(entity);
       } catch (Exception e) {
           handleException(e);
           return null;
       }
   }

    public static Object getTag(Entity entity, Object tag) {
        try {
            return entityGetTag.invoke(entity, tag);
        } catch (Exception e) {
            handleException(e);
            return null;
        }
    }

    public static void setTag(Entity entity, Object tag) {
        try {
            entityGetTag.invoke(entity, tag);
        } catch (Exception e) {
            handleException(e);
        }
    }

    public static void editTag(Entity entity, Consumer<Object> tagConsumer) {
        try {
            Object handle = EntityNms.getHandle(entity);
            Object compound = TagNms.create();
            entityGetTag.invoke(handle, compound);
            tagConsumer.accept(compound);
            entitySetTag.invoke(handle, compound);
        } catch (Exception e) {
            handleException(e);
        }
    }

    public static void setNoAI(Entity entity, boolean value) {
        editTag(entity, tag -> TagNms.set(tag, "NoAI", value));
    }

    public static void setSilent(Entity entity, boolean value) {
        editTag(entity, tag -> TagNms.set(tag, "Silent", value));
    }

    public static void setInvulnerable(Entity entity, boolean value) {
        editTag(entity, tag -> TagNms.set(tag,"Invulnerable", value));
    }

    public static void freeze(Entity entity, boolean value) {
        editTag(entity, tag -> {
            TagNms.set(tag,"NoAI", value);
            TagNms.set(tag, "Silent", value);
            TagNms.set(tag, "Invulnerable", value);
        });
    }

   private EntityNms(){}
}

@@ -270,16 +270,68 @@
 agNms;%0A%0A
+import java.lang.reflect.InvocationTargetException;%0A
 import j
@@ -659,23 +659,17 @@
  Method 
-entityG
+g
 etTag;%0A 
@@ -703,23 +703,17 @@
 hod 
-entityS
+s
 etTag;%0A%0A
    s
@@ -708,16 +708,17 @@
 etTag;%0A%0A
+ 
    stati
@@ -720,38 +720,40 @@
 static %7B%0A       
+ 
 try %7B%0A
+ 
            NMS_C
@@ -789,24 +789,25 @@
 (%22Entity%22);%0A
+ 
            B
@@ -881,16 +881,17 @@
         
+ 
 getHandl
@@ -946,31 +946,26 @@
 %0A           
-entityG
+ g
 etTag = NMS_
@@ -1015,31 +1015,26 @@
 %0A           
-entityS
+ s
 etTag = NMS_
@@ -1076,32 +1076,33 @@
 .CLASS);%0A       
+ 
 %7D catch (Excepti
@@ -1101,32 +1101,33 @@
 (Exception e) %7B%0A
+ 
            throw
@@ -1159,24 +1159,25 @@
 ception(e);%0A
+ 
        %7D%0A   
@@ -1176,19 +1176,21 @@
    %7D%0A   
+ 
 %7D%0A%0A
+ 
    publi
@@ -1228,24 +1228,25 @@
 y entity) %7B%0A
+ 
        try %7B
@@ -1253,24 +1253,25 @@
 %0A           
+ 
 return getHa
@@ -1294,24 +1294,25 @@
 ty);%0A       
+ 
 %7D catch (Exc
@@ -1315,32 +1315,33 @@
 (Exception e) %7B%0A
+ 
            handl
@@ -1358,32 +1358,33 @@
 (e);%0A           
+ 
 return null;%0A   
@@ -1387,18 +1387,20 @@
 %0A       
+ 
 %7D%0A
+ 
    %7D%0A%0A  
@@ -1491,23 +1491,17 @@
  return 
-entityG
+g
 etTag.in
@@ -1702,39 +1702,33 @@
 y %7B%0A            
-entityG
+g
 etTag.invoke(ent
@@ -2031,15 +2031,9 @@
     
-entityG
+g
 etTa
@@ -2118,15 +2118,9 @@
     
-entityS
+s
 etTa
@@ -2617,16 +2617,17 @@
 set(tag,
+ 
 %22Invulne
@@ -2772,16 +2772,17 @@
 set(tag,
+ 
 %22NoAI%22, 
@@ -2909,16 +2909,17 @@
   %7D%0A%0A   
+ 
 private 
@@ -2929,13 +2929,19 @@
 ityNms()
-%7B
+ %7B%0A    
 %7D%0A%7D%0A

Fix EntityNms bad indentation