package valandur.webapi.servlets;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import org.reflections.Reflections;
import org.spongepowered.api.event.Event;
import valandur.webapi.WebAPI;
import valandur.webapi.misc.Permission;
import valandur.webapi.cache.DataCache;
import valandur.webapi.json.JsonConverter;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Set;

public class ClassServlet extends WebAPIServlet {

    @Override
    @Permission(perm = "class")
    protected void handleGet(ServletData data) {
        String[] paths = data.getPathParts();

        if (paths.length == 0 || paths[0].isEmpty()) {
            String baseClass = data.getQueryPart("baseClass");
            if (baseClass != null) {
                try {
                    Class<?> c = Class.forName(baseClass);

                    WebAPI.getInstance().getLogger().info("Discovering all subclasses of '" + baseClass + "'...");
                    Set classes = WebAPI.getInstance().getReflections().getSubTypesOf(c);
                    WebAPI.getInstance().getLogger().info("Found " + classes.size() + " subclasses of '" + baseClass + "'");

                    data.addJson("base", c.getName());
                    data.addJson("classes", classes);
                } catch (ClassNotFoundException e) {
                    data.sendError(HttpServletResponse.SC_NOT_FOUND, "The class '" + baseClass + "' could not be found");
                }
            } else {
                ArrayNode node = JsonNodeFactory.instance.arrayNode();
                data.addJson("classes", JsonConverter.toJson(DataCache.getClasses().keySet().stream().map(Class::getName).toArray(String[]::new)));
            }
            return;
        }

        String className = paths[0];
        for (Map.Entry<Class, JsonNode> entry : DataCache.getClasses().entrySet()) {
            if (entry.getKey().getSimpleName().equalsIgnoreCase(className)) {
                data.addJson("class", entry.getValue());
                return;
            }
        }

        try {
            Class c = Class.forName(className);
            data.addJson("class", DataCache.getClass(c));
        } catch (ClassNotFoundException e) {
            data.sendError(HttpServletResponse.SC_NOT_FOUND, "The class '" + className + "' could not be found");
        }
    }
}

@@ -779,95 +779,226 @@
     
-String baseClass = data.getQueryPart(%22baseClass%22);%0A            if (baseClass != null) %7B
+ArrayNode node = JsonNodeFactory.instance.arrayNode();%0A            data.addJson(%22classes%22, JsonConverter.toJson(DataCache.getClasses().keySet().stream().map(Class::getName).toArray(String%5B%5D::new)));%0A            return;
 %0A   
@@ -1002,24 +1002,27 @@
         
+%7D%0A%0A
         
 try %7B%0A  
@@ -1005,37 +1005,61 @@
      %7D%0A%0A        
+S
 tr
-y %7B
+ing className = paths%5B0%5D;%0A
 %0A               
@@ -1043,32 +1043,38 @@
 hs%5B0%5D;%0A%0A        
+try %7B%0A
             Clas
@@ -1078,11 +1078,8 @@
 lass
-%3C?%3E
  c =
@@ -1097,25 +1097,246 @@
 ame(
-baseClass);%0A%0A    
+className);%0A%0A            if (paths.length %3C= 1) %7B%0A                data.addJson(%22class%22, DataCache.getClass(c));%0A                return;%0A            %7D%0A%0A            String op = paths%5B1%5D;%0A            if (op.equalsIgnoreCase(%22subclasses%22)) %7B%0A
     
@@ -1417,33 +1417,35 @@
 ses of '%22 + 
-baseClass
+c.getName()
  + %22'...%22);%0A
@@ -1460,20 +1460,16 @@
         
-  
-  
 Set clas
@@ -1530,20 +1530,16 @@
 sOf(c);%0A
-    
         
@@ -1629,33 +1629,35 @@
 ses of '%22 + 
-baseClass
+c.getName()
  + %22'%22);%0A%0A  
@@ -1650,28 +1650,24 @@
 () + %22'%22);%0A%0A
-    
             
@@ -1713,36 +1713,32 @@
                 
-    
 data.addJson(%22cl
@@ -1771,53 +1771,17 @@
     
- 
-   %7D catch (ClassNotFoundException e) %7B%0A    
+%7D else %7B%0A
     
@@ -1846,788 +1846,55 @@
 D, %22
-The class '%22 + baseClass + %22' could not be found%22);%0A                %7D%0A            %7D else %7B%0A                ArrayNode node = JsonNodeFactory.instance.arrayNode();%0A                data.addJson(%22classes%22, JsonConverter.toJson(DataCache.getClasses().keySet().stream().map(Class::getName).toArray(String%5B%5D::new)));%0A            %7D%0A            return;%0A        %7D%0A%0A        String className = paths%5B0%5D;%0A        for (Map.Entry%3CClass, JsonNode%3E entry : DataCache.getClasses().entrySet()) %7B%0A            if (entry.getKey().getSimpleName().equalsIgnoreCase(className)) %7B%0A                data.addJson(%22class%22, entry.getValue());%0A                return;%0A            %7D%0A        %7D%0A%0A        try %7B%0A            Class c = Class.forName(className);%0A            data.addJson(%22class%22, DataCache.getClass(c));
+Unknown operation '%22 + op + %22'%22);%0A            %7D
 %0A   

Rework class endpoint urls