/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard.retrace;

import proguard.classfile.util.ClassUtil;

import java.util.regex.*;

/**
 * This class can parse and format lines that represent stack frames
 * matching a given regular expression.
 *
 * @author Eric Lafortune
 */
public class FramePattern
{
    // The pattern matcher has problems with \\b against some unicode
    // characters, so we're no longer using \\b for classes and class members.
    private static final String REGEX_CLASS       = "(?:[^\\s\":./()]+\\.)*[^\\s\":./()]+";
    private static final String REGEX_CLASS_SLASH = "(?:[^\\s\":./()]+/)*[^\\s\":./()]+";
    private static final String REGEX_SOURCE_FILE = "[^:()]*";
    private static final String REGEX_LINE_NUMBER = "-?\\b\\d+\\b";
    private static final String REGEX_TYPE        = REGEX_CLASS + "(?:\\[\\])*";
    private static final String REGEX_MEMBER      = "<?[^\\s\":./()]+>?";
    private static final String REGEX_ARGUMENTS   = "(?:" + REGEX_TYPE + "(?:\\s*,\\s*" + REGEX_TYPE + ")*)?";

    private final char[]   expressionTypes     = new char[32];
    private final int      expressionTypeCount;
    private final Pattern  pattern;
    private final boolean  verbose;


    /**
     * Creates a new FramePattern.
     */
    public FramePattern(String regularExpression, boolean verbose)
    {
        // Construct the regular expression.
        StringBuffer expressionBuffer = new StringBuffer(regularExpression.length() + 32);

        int expressionTypeCount = 0;
        int index = 0;
        while (true)
        {
            int nextIndex = regularExpression.indexOf('%', index);
            if (nextIndex < 0                             ||
                nextIndex == regularExpression.length()-1 ||
                expressionTypeCount == expressionTypes.length)
            {
                break;
            }

            // Copy a literal piece of the input line.
            expressionBuffer.append(regularExpression.substring(index, nextIndex));
            expressionBuffer.append('(');

            char expressionType = regularExpression.charAt(nextIndex + 1);
            switch(expressionType)
            {
                case 'c':
                    expressionBuffer.append(REGEX_CLASS);
                    break;

                case 'C':
                    expressionBuffer.append(REGEX_CLASS_SLASH);
                    break;

                case 's':
                    expressionBuffer.append(REGEX_SOURCE_FILE);
                    break;

                case 'l':
                    expressionBuffer.append(REGEX_LINE_NUMBER);
                    break;

                case 't':
                    expressionBuffer.append(REGEX_TYPE);
                    break;

                case 'f':
                    expressionBuffer.append(REGEX_MEMBER);
                    break;

                case 'm':
                    expressionBuffer.append(REGEX_MEMBER);
                    break;

                case 'a':
                    expressionBuffer.append(REGEX_ARGUMENTS);
                    break;
            }

            expressionBuffer.append(')');

            expressionTypes[expressionTypeCount++] = expressionType;

            index = nextIndex + 2;
        }

        // Copy the last literal piece of the input line.
        expressionBuffer.append(regularExpression.substring(index));

        this.expressionTypeCount = expressionTypeCount;
        this.pattern             = Pattern.compile(expressionBuffer.toString());
        this.verbose             = verbose;
    }


    /**
     * Parses all frame information from a given line.
     * @param  line a line that represents a stack frame.
     * @return the parsed information, or null if the line doesn't match a
     *         stack frame.
     */
    public FrameInfo parse(String line)
    {
        // Try to match it against the regular expression.
        Matcher matcher = pattern.matcher(line);

        if (!matcher.matches())
        {
            return null;
        }

        // The line matched the regular expression.
        String className  = null;
        String sourceFile = null;
        int    lineNumber = 0;
        String type       = null;
        String fieldName  = null;
        String methodName = null;
        String arguments  = null;

        // Extract a class name, a line number, a type, and
        // arguments.
        for (int expressionTypeIndex = 0; expressionTypeIndex < expressionTypeCount; expressionTypeIndex++)
        {
            int startIndex = matcher.start(expressionTypeIndex + 1);
            if (startIndex >= 0)
            {
                String match = matcher.group(expressionTypeIndex + 1);

                char expressionType = expressionTypes[expressionTypeIndex];
                switch (expressionType)
                {
                    case 'c':
                        className = match;
                        break;

                    case 'C':
                        className = ClassUtil.externalClassName(match);
                        break;

                    case 's':
                        sourceFile = match;
                        break;

                    case 'l':
                        lineNumber = Integer.parseInt(match);
                        break;

                    case 't':
                        type = match;
                        break;

                    case 'f':
                        fieldName = match;
                        break;

                    case 'm':
                        methodName = match;
                        break;

                    case 'a':
                        arguments = match;
                        break;
                }
            }
        }

        return new FrameInfo(className,
                             sourceFile,
                             lineNumber,
                             type,
                             fieldName,
                             methodName,
                             arguments);
    }


    /**
     * Formats the given frame information based on the given template line.
     * It is the reverse of {@link #parse(String)}, but optionally with
     * different frame information.
     * @param  line      a template line that represents a stack frame.
     * @param  frameInfo information about a stack frame.
     * @return the formatted line, or null if the line doesn't match a
     *         stack frame.
     */
    public String format(String line, FrameInfo frameInfo)
    {
        // Try to match it against the regular expression.
        Matcher matcher = pattern.matcher(line);

        if (!matcher.matches())
        {
            return null;
        }

        StringBuffer formattedBuffer = new StringBuffer();

        int lineIndex = 0;
        for (int expressionTypeIndex = 0; expressionTypeIndex < expressionTypeCount; expressionTypeIndex++)
        {
            int startIndex = matcher.start(expressionTypeIndex + 1);
            if (startIndex >= 0)
            {
                int    endIndex = matcher.end(expressionTypeIndex + 1);
                String match    = matcher.group(expressionTypeIndex + 1);

                // Copy a literal piece of the input line.
                formattedBuffer.append(line.substring(lineIndex, startIndex));

                // Copy a matched and translated piece of the input line.
                char expressionType = expressionTypes[expressionTypeIndex];
                switch (expressionType)
                {
                    case 'c':
                        formattedBuffer.append(frameInfo.getClassName());
                        break;

                    case 'C':
                        formattedBuffer.append(ClassUtil.internalClassName(frameInfo.getClassName()));
                        break;

                    case 's':
                        formattedBuffer.append(frameInfo.getSourceFile());
                        break;

                    case 'l':
                        formattedBuffer.append(frameInfo.getLineNumber());
                        break;

                    case 't':
                        formattedBuffer.append(frameInfo.getType());
                        break;

                    case 'f':
                        if (verbose)
                        {
                            formattedBuffer.append(frameInfo.getType()).append(' ');
                        }
                        formattedBuffer.append(frameInfo.getFieldName());
                        break;

                    case 'm':
                        if (verbose)
                        {
                            formattedBuffer.append(frameInfo.getType()).append(' ');
                        }
                        formattedBuffer.append(frameInfo.getMethodName());
                        if (verbose)
                        {
                            formattedBuffer.append('(').append(frameInfo.getArguments()).append(')');
                        }
                        break;

                    case 'a':
                        formattedBuffer.append(frameInfo.getArguments());
                        break;
                }

                // Skip the original element whose replacement value
                // has just been appended.
                lineIndex = endIndex;
            }
        }

        // Copy the last literal piece of the input line.
        formattedBuffer.append(line.substring(lineIndex));

        // Return the formatted line.
        return formattedBuffer.toString();
    }
}
