/*
 * Trident - A Multithreaded Server Alternative
 * Copyright 2014 The TridentSDK Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.tridentsdk.util;

import net.tridentsdk.Trident;
import net.tridentsdk.docs.InternalUseOnly;
import net.tridentsdk.docs.Volatile;
import net.tridentsdk.plugin.TridentPluginHandler;
import org.apache.log4j.*;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Random;

@Volatile(policy = "Init FIRST", reason = "Requires SLF4J to be configured", fix = "first static block in main class")
public final class TridentLogger {
    private static final String[] ERRORS = {
            "Aw, Mazen! Really?",
            "Uh no, I don't want to eat that",
            "21 occurred, not acceptable.",
            "69Overflow",
            "I feel funny",
            "Be safe while keking, or naw",
            "Dang",
            "PierreC farts, then this happens",
            "I DIDN'T DO IT!!",
            "bruh",
            "This wasn't supposed to happen. It did anyways.",
            "Bukkit 1.8 not found, contact Dinnerbone",
            "Huston, we have a problem",
            "Oh great, a stacktrace. Can't we write good software for once?",
            "It's not a bug, it's a feature!"
    };

    private TridentLogger() {
    }

    @InternalUseOnly
    public static void init() {
        ConsoleAppender console = new ConsoleAppender(); //create appender
        String PATTERN = "%d{dd MMM HH:mm} [%p] %m%n";
        console.setLayout(new PatternLayout(PATTERN));
        console.setThreshold(Level.INFO);
        console.activateOptions();

        Logger.getRootLogger().addAppender(console);

        FileAppender fa = new FileAppender();
        fa.setName("FileLogger");
        fa.setFile("trident.log");
        fa.setLayout(new PatternLayout(PATTERN));
        fa.setThreshold(Level.DEBUG);
        fa.setAppend(true);
        fa.activateOptions();

        //add appender to any Logger (here is root)
        Logger.getRootLogger().addAppender(fa);
    }

    private static Class<?> getCaller() {
        StackTraceElement[] elements = Thread.currentThread().getStackTrace();
        StackTraceElement element = elements[4];

        try {
            return Class.forName(element.getClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static org.slf4j.Logger getLogger() {
        return LoggerFactory.getLogger(getCaller());
    }

    public static void log(String item) {
        getLogger().info(item);
    }

    public static void error(String message) {
        getLogger().error(message);
    }

    public static void error(Throwable throwable) {
        getLogger().error("========  BEGIN ERROR =========");

        getLogger().error("");

        Random rand = new Random();
        int randomNum = rand.nextInt((ERRORS.length - 1) + 1) + 0;

        getLogger().error(ERRORS[randomNum]);
        getLogger().error("Error occurred in thread \"" + Thread.currentThread().getName() + "\": " + throwable.getMessage());
        getLogger().error("======== Generating Debug Information =========");
        StackTraceElement main = throwable.getStackTrace()[0];
        getLogger().error("Class:  " + main.getClassName());
        getLogger().error("Method: " + main.getMethodName());
        getLogger().error("Line:   " + main.getLineNumber());
        getLogger().error("========   Ending Debug Information   =========");

        getLogger().error("");

        getLogger().error("======== Printing Stacktrace =========");
        for (StackTraceElement element : throwable.getStackTrace())
            getLogger().error("    at " + element.getClassName() + "." +
                    element.getMethodName() + "(...) : " +
                    (element.getLineNumber() > 0 ? element.getLineNumber() : "Native method"));
        getLogger().error("========  Ending Stacktrace  =========");

        getLogger().error("");

        getLogger().error("========     Server info    =========");
        getLogger().error("Trident version: " + Trident.getVersion());
        getLogger().error("Plugins:         " +
                Arrays.toString(TridentPluginHandler.getPluginExecutorFactory().values().toArray()));
        getLogger().error("Java:            version " + System.getProperty("java.version") + " distributed by " +
                System.getProperty("java.vendor"));
        getLogger().error("OS:              running " +
                System.getProperty("os.name") + " version " +
                System.getProperty("os.version") + " " +
                System.getProperty("os.arch"));
        getLogger().error("======== Ending Server info =========");

        getLogger().error("");

        getLogger().error("========      END ERROR     =========");
    }
}

@@ -1197,109 +1197,60 @@
    %22
-Uh no, I don't want to eat that%22,%0A            %2221 occurred, not acceptable.%22,%0A            %2269Overflow
+I feel funny%22,%0A            %229 + 10 does not equal 21
 %22,%0A 
@@ -1257,36 +1257,28 @@
            %22
-I feel funny
+Dang
 %22,%0A         
@@ -1285,155 +1285,84 @@
    %22
-Be safe while keking, or naw%22,%0A            %22Dang%22,%0A            %22PierreC farts, then this happens%22,%0A            %22I DIDN'T DO IT!!%22,%0A            %22bru
+Thanks, Obama%22,%0A            %22God dammit Tony Abbot, the fax didn't go throug
 h%22,%0A
@@ -1616,15 +1616,26 @@
    %22
-It's no
+Trust me this isn'
 t a 
@@ -2113,24 +2113,25 @@
 Appender();%0A
+%0A
         fa.s

Update TridentLogger.java