package com.yourmajesty.debug
{
    /**
     * Utilities for inspecting the stack at a given moment in the virtual machine's execution.
     * If you use this code, please retain this author tag:
     * @author Roger Braunstein | Your Majesty | 2007
     */
    public class Stack
    {
        /**
         * Get the entire stack trace as a single string.
         */
        public static function getRawStackTrace():String
        {
            var stackTrace:String;
            try
            {
                throw new Error();
            } catch (error:Error) {
                stackTrace = error.getStackTrace();
            }
            return stackTrace;
        }
        
        /**
         * Returns the entire stack trace as an array.
         * @param ignoreLevels    ignore the top N entries in the stack trace. For utilities that use this method,
         *                         you can trim off both the call to this method, and any intermediary calls which
         *                         aren't part of your target code.
         */
        public static function getStackEntries(ignoreLevels:int = 0):Array
        {
            var stackTrace:String = getRawStackTrace();
            var stack:Array = stackTrace.split(/^\s*at\s+/m);
            stack.splice(0, ignoreLevels + 1);
            return stack;
        }
        
        /**
         * Parse a String stack entry into an object with lots of parameters (listed in the regexp with angular brackets).
         */
        public static function getPartsFromStackTraceEntry(stackEntry:String):Object
        {
            return stackEntry.match(/(?P<package>[\w\d\.]+)::(?P<classname>[\w\d\.\:]*?)(?P<isStatic>\$?)\/((?P<scope>[\w\d\.\:]+)::)?(?P<method>[\w\d]+\(\))(\[(?P<filename>[\w\d\\\/\.]+):(?P<line>\d+)\])?/);
        }
        
        /**
         * Reformat a long stack trace entry into a simplified one with only the package, classname, and method (if possible).
         */
        public static function getSimplifiedStackTraceEntry(stackEntry:String):String
        {
            var o:Object = getPartsFromStackTraceEntry(stackEntry);
            return (o)?(o['package'] + '.' + o['classname'] + '::' + o['method']):stackEntry;
        }
    }
}