<commit_before>package common;

import java.util.HashMap;
import java.util.Map;

import javax.swing.JOptionPane;

import enums.AnsiColors;

/**
 * Debug utility class with ANSI colors support.
 * 
 * @author tlee
 */
public class Debug {
	static class NotYetImplemented {
		private int occurrences = 0;
		private final String location;

		public NotYetImplemented(String loc) {
			this.location = loc;
		}

		public boolean grab(String loc) {
			if (this.location.equals(loc) && !this.hasReachedLimit()) {
				this.increment();
				return true;
			}
			return false;
		}

		public void increment() {
			this.occurrences++;
		}

		public boolean hasReachedLimit() {
			return this.occurrences >= Debug.MaxDuplicateLogOccurrences;
		}
	}

	/**
	 * Logs information in yellow text.
	 * 
	 * @param msg
	 */
	public static void log(String msg) {
		Debug.printColor(AnsiColors.Yellow, Debug.createString(msg));
	}

	/**
	 * Prints out information in green text.
	 * 
	 * @param msg
	 */
	public static void info(String msg) {
		Debug.printColor(AnsiColors.Green, Debug.createString(msg));
	}

	/**
	 * Displays error in bright red text.
	 * 
	 * @param msg
	 */
	public static void error(String msg) {
		Debug.printColor(AnsiColors.BrightRed, Debug.createString(msg));
	}

	/**
	 * Displays error in bright red text, and prints out the exception in dark red text.
	 * 
	 * @param msg
	 * @param e
	 */
	public static void error(String msg, Exception e) {
		Debug.printColor(AnsiColors.BrightRed, Debug.createString(msg));
		Debug.printColor(AnsiColors.Red, Debug.createExceptionString(e));
	}

	/**
	 * Displays error exception in dark red text.
	 * 
	 * @param e
	 */
	public static void exception(Exception e) {
		Debug.printColor(AnsiColors.Red, Debug.createExceptionString(e));
	}

	/**
	 * Displays an alert message box with the error message and line number.
	 * 
	 * @param e
	 */
	public static void showExceptionCause(Exception e) {
		Debug.showExceptionCause("", e);
	}

	/**
	 * Displays an alert message box with a customized message, the error message, and the line number.
	 * 
	 * @param msg
	 * @param e
	 */
	public static void showExceptionCause(String msg, Exception e) {
		if (msg == null) {
			StackTraceElement threadStack = Thread.currentThread().getStackTrace()[2];
			String threadCause = threadStack.getClassName() + ":" + threadStack.getLineNumber();
			JOptionPane.showMessageDialog(null, "Debug.showExceptionCause encountered null message.\n" + threadCause);
			return;
		}
		StackTraceElement element = e.getStackTrace()[0];
		String cause = "(" + element.getFileName() + ":" + element.getLineNumber() + ")";
		if (!msg.isBlank()) {
			msg += "\n";
		}
		msg += e.getMessage() + " " + cause;
		JOptionPane.showMessageDialog(null, msg);
	}

	/**
	 * Nifty way of marking where in the code, have we not yet implemented any Java code.
	 */
	public static void notYetImplemented() {
		String key = Debug.createString("", 3);
		NotYetImplemented nyi = Debug.notYetImplementedTracker.getOrDefault(key, new NotYetImplemented(key));
		if (nyi.grab(key)) {
			String msg = null;
			int index = 2;
			do {
				msg = Debug.createString("Not yet implemented", index);
				index--;
			}
			while (msg == null || (msg.contains("$") && index > 0));
			Debug.printColor(AnsiColors.BrightMagenta, msg);
			Debug.notYetImplementedTracker.put(key, nyi);
		}
	}

	// -----------------------------------------------------------------
	// Private static methods and class member fields.

	private static final int MinimumStringLength = 17;
	private static final int TabLength = 8;
	protected static final int MaxDuplicateLogOccurrences = 1;
	private static Map<String, NotYetImplemented> notYetImplementedTracker = new HashMap<>();

	/**
	 * Handles wrapping the input string with ANSI color tags.
	 * 
	 * @param color
	 * @param input
	 */
	private static void printColor(AnsiColors color, String input) {
		System.out.println(color.getAnsiCode() + input + AnsiColors.Clear.getAnsiCode());
	}

	/**
	 * Builds the log messages in a readable format for developers.
	 * 
	 * @param msg
	 * @param index
	 *            Specify which stack trace element to choose from.
	 * @return
	 */
	private static String createString(String msg, int index) {
		StackTraceElement[] elements = new Throwable().getStackTrace();
		StackTraceElement element = elements[index];
		String className = element.getClassName() + ":" + element.getLineNumber();
		String tabs = "\t";
		int length = className.length();
		while (length < Debug.MinimumStringLength) {
			tabs = tabs.concat("\t");
			length += Debug.TabLength;
		}
		return className + tabs + "- " + msg;
	}

	/**
	 * Builds the log messages in a readable format for developers.
	 * 
	 * @param msg
	 * @return
	 */
	private static String createString(String msg) {
		return createString(msg, 2);
	}

	/**
	 * Builds a simplified exception message thrown out by the actual class object containing the bug.
	 * Does not display anything related with Java SDK internal classes.
	 * <commit_msg>Fixed a bug related to obtaining the incorrect stack trace element.<commit_after>package common;

import java.util.HashMap;
import java.util.Map;

import javax.swing.JOptionPane;

import enums.AnsiColors;

/**
 * Debug utility class with ANSI colors support.
 * 
 * @author tlee
 */
public class Debug {
	static class NotYetImplemented {
		private int occurrences = 0;
		private final String location;

		public NotYetImplemented(String loc) {
			this.location = loc;
		}

		public boolean grab(String loc) {
			if (this.location.equals(loc) && !this.hasReachedLimit()) {
				this.increment();
				return true;
			}
			return false;
		}

		public void increment() {
			this.occurrences++;
		}

		public boolean hasReachedLimit() {
			return this.occurrences >= Debug.MaxDuplicateLogOccurrences;
		}
	}

	/**
	 * Logs information in yellow text.
	 * 
	 * @param msg
	 */
	public static void log(String msg) {
		Debug.printColor(AnsiColors.Yellow, Debug.createString(msg));
	}

	/**
	 * Prints out information in green text.
	 * 
	 * @param msg
	 */
	public static void info(String msg) {
		Debug.printColor(AnsiColors.Green, Debug.createString(msg));
	}

	/**
	 * Displays error in bright red text.
	 * 
	 * @param msg
	 */
	public static void error(String msg) {
		Debug.printColor(AnsiColors.BrightRed, Debug.createString(msg));
	}

	/**
	 * Displays error in bright red text, and prints out the exception in dark red text.
	 * 
	 * @param msg
	 * @param e
	 */
	public static void error(String msg, Exception e) {
		Debug.printColor(AnsiColors.BrightRed, Debug.createString(msg));
		Debug.printColor(AnsiColors.Red, Debug.createExceptionString(e));
	}

	/**
	 * Displays error exception in dark red text.
	 * 
	 * @param e
	 */
	public static void exception(Exception e) {
		Debug.printColor(AnsiColors.Red, Debug.createExceptionString(e));
	}

	/**
	 * Displays an alert message box with the error message and line number.
	 * 
	 * @param e
	 */
	public static void showExceptionCause(Exception e) {
		Debug.showExceptionCause("", e);
	}

	/**
	 * Displays an alert message box with a customized message, the error message, and the line number.
	 * 
	 * @param msg
	 * @param e
	 */
	public static void showExceptionCause(String msg, Exception e) {
		if (msg == null) {
			StackTraceElement threadStack = Thread.currentThread().getStackTrace()[2];
			String threadCause = threadStack.getClassName() + ":" + threadStack.getLineNumber();
			JOptionPane.showMessageDialog(null, "Debug.showExceptionCause encountered null message.\n" + threadCause);
			return;
		}
		StackTraceElement element = e.getStackTrace()[0];
		String cause = "(" + element.getFileName() + ":" + element.getLineNumber() + ")";
		if (!msg.isBlank()) {
			msg += "\n";
		}
		msg += e.getMessage() + " " + cause;
		JOptionPane.showMessageDialog(null, msg);
	}

	/**
	 * Nifty way of marking where in the code, have we not yet implemented any Java code.
	 */
	public static void notYetImplemented() {
		String key = Debug.createString("", 3);
		NotYetImplemented nyi = Debug.notYetImplementedTracker.getOrDefault(key, new NotYetImplemented(key));
		if (nyi.grab(key)) {
			String msg = null;
			int index = 2;
			do {
				msg = Debug.createString("Not yet implemented", index);
				index--;
			}
			while (msg == null || (msg.contains("$") && index > 0));
			Debug.printColor(AnsiColors.BrightMagenta, msg);
			Debug.notYetImplementedTracker.put(key, nyi);
		}
	}

	// -----------------------------------------------------------------
	// Private static methods and class member fields.

	private static final int MinimumStringLength = 17;
	private static final int TabLength = 8;
	protected static final int MaxDuplicateLogOccurrences = 1;
	private static Map<String, NotYetImplemented> notYetImplementedTracker = new HashMap<>();

	/**
	 * Handles wrapping the input string with ANSI color tags.
	 * 
	 * @param color
	 * @param input
	 */
	private static void printColor(AnsiColors color, String input) {
		System.out.println(color.getAnsiCode() + input + AnsiColors.Clear.getAnsiCode());
	}

	/**
	 * Builds the log messages in a readable format for developers.
	 * 
	 * @param msg
	 * @param index
	 *            Specify which stack trace element to choose from.
	 * @return
	 */
	private static String createString(String msg, int index) {
		StackTraceElement[] elements = new Throwable().getStackTrace();
		StackTraceElement element = elements[index];
		String className = element.getClassName() + ":" + element.getLineNumber();
		String tabs = "\t";
		int length = className.length();
		while (length < Debug.MinimumStringLength) {
			tabs = tabs.concat("\t");
			length += Debug.TabLength;
		}
		return className + tabs + "- " + msg;
	}

	/**
	 * Builds the log messages in a readable format for developers.
	 * 
	 * @param msg
	 * @return
	 */
	private static String createString(String msg) {
		return createString(msg, 3);
	}

	/**
	 * Builds a simplified exception message thrown out by the actual class object containing the bug.
	 * Does not display anything related with Java SDK internal classes.
	 * 
{'fraction_non_alphanumeric': 0.12934782608695652, 'fraction_numerical': 0.002173913043478261, 'mean_word_length': 3.370034542314335, 'pattern_counts': {'":': 6, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5201502', 'n_tokens_mistral': 3372, 'n_tokens_neox': 2955, 'n_words': 898}