package com.btk5h.skriptmirror.util;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.SyntaxElementInfo;
import ch.njol.skript.lang.function.Function;
import ch.njol.skript.lang.function.Parameter;
import ch.njol.skript.log.*;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class SkriptReflection {
  private static Field PATTERNS;
  private static Field PARAMETERS;
  private static Field HANDLERS;

  static {
    Field _FIELD;
    try {
      _FIELD = SyntaxElementInfo.class.getDeclaredField("patterns");
      _FIELD.setAccessible(true);
      PATTERNS = _FIELD;
    } catch (NoSuchFieldException e) {
      Skript.warning("Skript's pattern info field could not be resolved. " +
          "Custom syntax will not work.");
    }

    try {
      _FIELD = Function.class.getDeclaredField("parameters");
      _FIELD.setAccessible(true);
      PARAMETERS = _FIELD;
    } catch (NoSuchFieldException e) {
      Skript.warning("Skript's parameters field could not be resolved. " +
          "Class proxies will not work.");
    }

    try {
      _FIELD = SkriptLogger.class.getDeclaredField("handlers");
      _FIELD.setAccessible(true);
      HANDLERS = _FIELD;
    } catch (NoSuchFieldException e) {
      Skript.warning("Skript's handlers field could not be resolved. Some Skript warnings may not be available.");
    }
  }

  public static void setPatterns(SyntaxElementInfo<?> info, String[] patterns) {
    if (PATTERNS != null) {
      try {
        PATTERNS.set(info, patterns);
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }
  }

  public static Parameter<?>[] getParameters(Function function) {
    if (PARAMETERS != null) {
      try {
        return ((Parameter<?>[]) PARAMETERS.get(function));
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }
    throw new IllegalStateException();
  }

  public static void printLog(RetainingLogHandler logger) {
    logger.stop();
    if (HANDLERS != null) {
      HandlerList handler;
      try {
        handler = (HandlerList) HANDLERS.get(logger);
      } catch (IllegalAccessException e) {
        e.printStackTrace();
        return;
      }

      Iterator<LogHandler> handlers = handler.iterator();
      LogHandler nextHandler;
      List<LogHandler> parseLogs = new ArrayList<>();

      while (handlers.hasNext() && (nextHandler = handlers.next()) instanceof ParseLogHandler) {
        parseLogs.add(nextHandler);
      }

      parseLogs.forEach(LogHandler::stop);
      SkriptLogger.logAll(logger.getLog());
    }
  }
}

@@ -1488,38 +1488,8 @@
 ) %7B%0A
-    if (PATTERNS != null) %7B%0A  
     
@@ -1496,26 +1496,24 @@
 try %7B%0A      
-  
 PATTERNS.set
@@ -1530,18 +1530,16 @@
 terns);%0A
-  
     %7D ca
@@ -1569,34 +1569,32 @@
 tion e) %7B%0A      
- 
- 
 e.printStackTrac
@@ -1594,32 +1594,24 @@
 ackTrace();%0A
-      %7D%0A
     %7D%0A  %7D%0A%0A 
@@ -1679,40 +1679,8 @@
 ) %7B%0A
-    if (PARAMETERS != null) %7B%0A  
     
@@ -1687,26 +1687,24 @@
 try %7B%0A      
- 
- 
 return ((Par
@@ -1743,26 +1743,24 @@
 tion));%0A    
-  
 %7D catch (Ill
@@ -1776,34 +1776,32 @@
 sException e) %7B%0A
-  
       e.printSta
@@ -1811,24 +1811,16 @@
 race();%0A
-      %7D%0A
     %7D%0A  
@@ -1944,38 +1944,8 @@
 ();%0A
-    if (HANDLERS != null) %7B%0A  
     
@@ -1969,26 +1969,22 @@
 er;%0A    
-  
 try %7B%0A
-  
       ha
@@ -2023,26 +2023,24 @@
 et(logger);%0A
-  
     %7D catch 
@@ -2070,26 +2070,24 @@
  e) %7B%0A      
-  
 e.printStack
@@ -2097,26 +2097,24 @@
 ce();%0A      
-  
 return;%0A    
@@ -2109,31 +2109,27 @@
 return;%0A    
-  
 %7D%0A%0A
-  
     Iterator
@@ -2176,18 +2176,16 @@
 ();%0A    
- 
- 
 LogHandl
@@ -2200,18 +2200,16 @@
 andler;%0A
-  
     List
@@ -2253,18 +2253,16 @@
 t%3C%3E();%0A%0A
-  
     whil
@@ -2350,26 +2350,24 @@
 er) %7B%0A      
-  
 parseLogs.ad
@@ -2390,19 +2390,15 @@
     
-  
 %7D%0A%0A    
- 
- 
 pars
@@ -2430,18 +2430,16 @@
 :stop);%0A
-  
     Skri
@@ -2472,20 +2472,14 @@
 Log());%0A
-    %7D%0A
   %7D%0A%7D%0A

Remove null checks