/*
 * Copyright (c) 2003 The Visigoth Software Society. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowledgement:
 *       "This product includes software developed by the
 *        Visigoth Software Society (http://www.visigoths.org/)."
 *    Alternately, this acknowledgement may appear in the software itself,
 *    if and wherever such third-party acknowledgements normally appear.
 *
 * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
 *    project contributors may be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact visigoths@visigoths.org.
 *
 * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
 *    nor may "FreeMarker" or "Visigoth" appear in their names
 *    without prior written permission of the Visigoth Software Society.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Visigoth Software Society. For more
 * information on the Visigoth Software Society, please see
 * http://www.visigoths.org/
 */

package freemarker.core;

import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.utility.SecurityUtilities;
import freemarker.template.utility.StringUtil;

/**
 * Parsing-time exception in a template (as opposed to runtime: {@link TemplateException}). This usually signals
 * syntactical/lexical errors.
 * 
 * Note that on JavaCC-level lexical errors throw {@link TokenMgrError} instead of this, however with the API-s that
 * most users use those will be wrapped into {@link ParseException}-s. 
 *
 * This is a modified version of file generated by JavaCC from FTL.jj.
 * You can modify this class to customize the error reporting mechanisms so long as the public interface
 * remains compatible with the original.
 * 
 * @see TokenMgrError
 */
public class ParseException extends java.io.IOException implements FMParserConstants {

    /**
     * This is the last token that has been consumed successfully.  If
     * this object has been created due to a parse error, the token
     * following this token will (therefore) be the first error token.
     */
    public Token currentToken;

    private static volatile Boolean jbossToolsMode;

    private boolean messageAndDescriptionRendered;
    private String message;
    private String description; 

    public int columnNumber, lineNumber;
    public int endColumnNumber, endLineNumber;

    /**
     * Each entry in this array is an array of integers.  Each array
     * of integers represents a sequence of tokens (by their ordinal
     * values) that is expected at this point of the parse.
     */
    public int[][] expectedTokenSequences;

    /**
     * This is a reference to the "tokenImage" array of the generated
     * parser within which the parse error occurred.  This array is
     * defined in the generated ...Constants interface.
     */
    public String[] tokenImage;

    /**
     * The end of line string for this machine.
     */
    protected String eol = SecurityUtilities.getSystemProperty("line.separator", "\n");

    /** @deprecated Will be remove without replacement in 2.4. */
    protected boolean specialConstructor;  

    // This was no part of Throwable on J2SE 1.2; remove in Java 5
    private final Throwable cause;

    private String templateName;

    /**
     * This constructor is used by the method "generateParseException"
     * in the generated parser.  Calling this constructor generates
     * a new object of this type with the fields "currentToken",
     * "expectedTokenSequences", and "tokenImage" set.
     * This constructor calls its super class with the empty string
     * to force the "toString" method of parent class "Throwable" to
     * print the error message in the form:
     *     ParseException: <result of getMessage>
     */
    public ParseException(Token currentTokenVal,
            int[][] expectedTokenSequencesVal,
            String[] tokenImageVal
            )
    {
        super("");
        cause = null;
        currentToken = currentTokenVal;
        specialConstructor = true;
        expectedTokenSequences = expectedTokenSequencesVal;
        tokenImage = tokenImageVal;
        lineNumber = currentToken.next.beginLine;
        columnNumber = currentToken.next.beginColumn;
        endLineNumber = currentToken.next.endLine;
        endColumnNumber = currentToken.next.endColumn;
    }

    /**
     * The following constructors are for use by you for whatever
     * purpose you can think of.  Constructing the exception in this
     * manner makes the exception behave in the normal way - i.e., as
     * documented in the class "Throwable".  The fields "errorToken",
     * "expectedTokenSequences", and "tokenImage" do not contain
     * relevant information.  The JavaCC generated code does not use
     * these constructors.
     * 
     * @deprecated
     */
    protected ParseException() {
        super();
        cause = null;
    }

    /**
     * @deprecated Use a constructor to which you can also pass the template, and the end positions.
     */
    public ParseException(String description, int lineNumber, int columnNumber) {
        this(description, (Template) null, lineNumber, columnNumber, null);
    }

    /**
     * @since 2.3.21
     */
    public ParseException(String description, Template template,
            int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber) {
        this(description, template, lineNumber, columnNumber, endLineNumber, endColumnNumber, null);      
    }

    /**
     * @since 2.3.21
     */
    public ParseException(String description, Template template,
            int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
            Throwable cause) {
        this(description,
                template == null ? null : template.getName(),
                        lineNumber, columnNumber,
                        endLineNumber, endColumnNumber,
                        cause);      
    }
    
    /**
     * @deprecated Use {@link #ParseException(String, Template, int, int, int, int)} instead, as IDE-s need the end
     * position of the error too.
     * @since 2.3.20
     */
    public ParseException(String description, Template template, int lineNumber, int columnNumber) {
        this(description, template, lineNumber, columnNumber, null);      
    }

    /**
     * @deprecated Use {@link #ParseException(String, Template, int, int, int, int, Throwable)} instead, as IDE-s need
     * the end position of the error too.
     * @since 2.3.20
     */
    public ParseException(String description, Template template, int lineNumber, int columnNumber, Throwable cause) {
        this(description,
                template == null ? null : template.getName(),
                        lineNumber, columnNumber,
                        0, 0,
                        cause);      
    }

    /**
     * @since 2.3.20
     */
    public ParseException(String description, Template template, Token tk) {
        this(description, template, tk, null);
    }

    /**
     * @since 2.3.20
     */
    public ParseException(String description, Template template, Token tk, Throwable cause) {
        this(description,
                template == null ? null : template.getName(),
                        tk.beginLine, tk.beginColumn,
                        tk.endLine, tk.endColumn,
                        cause);
    }

    /**
     * @since 2.3.20
     */
    public ParseException(String description, TemplateObject tobj) {
        this(description, tobj, null);
    }

    /**
     * @since 2.3.20
     */
    public ParseException(String description, TemplateObject tobj, Throwable cause) {
        this(description,
                tobj.getTemplate() == null ? null : tobj.getTemplate().getName(),
                        tobj.beginLine, tobj.beginColumn,
                        tobj.endLine, tobj.endColumn,
                        cause);
    }

    private ParseException(String description, String templateName,
            int lineNumber, int columnNumber,
            int endLineNumber, int endColumnNumber,
            Throwable cause) {
        super(description);  // but we override getMessage, so it will be different
        this.cause = cause;
        this.description = description; 
        this.templateName = templateName;
        this.lineNumber = lineNumber;
        this.columnNumber = columnNumber;
        this.endLineNumber = endLineNumber;
        this.endColumnNumber = endColumnNumber;
    }

    /**
     * Should be used internally only; sets the name of the template that contains the error.
     * This is needed as the constructor that JavaCC automatically calls doesn't pass in the template, so we
     * set it somewhere later in an exception handler. 
     */
    public void setTemplateName(String templateName) {
        this.templateName = templateName;
        synchronized (this) {
            messageAndDescriptionRendered = false;
            message = null;
        }
    }

    public Throwable getCause() {
        return cause;
    }

    /**
     * Returns the error location plus the error description.
     * 
     * @see #getDescription()
     * @see #getTemplateName()
     * @see #getLineNumber()
     * @see #getColumnNumber()
     */
    public String getMessage() {
        synchronized (this) {
            if (messageAndDescriptionRendered) return message;
        }
        renderMessageAndDescription();
        synchronized (this) {
            return message;
        }
    }

    private String getDescription() {
        synchronized (this) {
            if (messageAndDescriptionRendered) return description;
        }
        renderMessageAndDescription();
        synchronized (this) {
            return description;
        }
    }
    
    /**
     * Returns the description of the error without error location or source quotations, or {@code null} if there's no
     * description available. This is useful in editors (IDE-s) where the error markers and the editor window itself
     * already carry this information, so it's redundant the repeat in the error dialog.
     */
    public String getEditorMessage() {
        return getDescription();
    }

    /**
     * Returns the name (template-root relative path) of the template whose parsing was failed.
     * Maybe {@code null} if this is a non-stored template. 
     * 
     * @since 2.3.20
     */
    public String getTemplateName() {
        return templateName;
    }

    /**
     * 1-based line number of the failing section, or 0 is the information is not available.
     */
    public int getLineNumber() {
        return lineNumber;
    }

    /**
     * 1-based column number of the failing section, or 0 is the information is not available.
     */
    public int getColumnNumber() {
        return columnNumber;
    }

    /**
     * 1-based line number of the failing section, or 0 is the information is not available.
     */
    public int getEndLineNumber() {
        return endLineNumber;
    }

    /**
     * 1-based column number of the failing section, or 0 is the information is not available.
     */
    public int getEndColumnNumber() {
        return endColumnNumber;
    }

    private void renderMessageAndDescription() {
        String desc = getOrRenderDescription();

        String prefix;
        if (!isInJBossToolsMode()) {
            prefix = "Parsing error "
                    + MessageUtil.formatLocationForSimpleParsingError(templateName, lineNumber, columnNumber)
                    + ":\n";  
        } else {
            prefix = "[col. " + columnNumber + "] ";
        }

        String msg = prefix + desc;
        desc = msg.substring(prefix.length());  // so we reuse the backing char[]

        synchronized (this) {
            message = msg;
            description = desc;
            messageAndDescriptionRendered = true;
        }
    }

    private boolean isInJBossToolsMode() {
        if (jbossToolsMode == null) {
            try {
                jbossToolsMode =
                        ParseException.class.getClassLoader().toString().indexOf(
                                "[org.jboss.ide.eclipse.freemarker:") != -1
                                ? Boolean.TRUE : Boolean.FALSE;
            } catch (Throwable e) {
                jbossToolsMode = Boolean.FALSE;
            }
        }
        return jbossToolsMode.booleanValue();
    }

    /**
     * Returns the description of the error without the error location, or {@code null} if there's no description
     * available.
     */
    private String getOrRenderDescription() {
        synchronized (this) {
            if (description != null) return description;  // When we already have it from the constructor
        }

        String tokenErrDesc;
        if (currentToken != null) {
            tokenErrDesc = getCustomTokenErrorDescription();
            if (tokenErrDesc == null) {
                // The default JavaCC message generation stuff follows.
                StringBuffer expected = new StringBuffer();
                int maxSize = 0;
                for (int i = 0; i < expectedTokenSequences.length; i++) {
                    if (i != 0) {
                        expected.append(eol);
                    }
                    expected.append("    ");
                    if (maxSize < expectedTokenSequences[i].length) {
                        maxSize = expectedTokenSequences[i].length;
                    }
                    for (int j = 0; j < expectedTokenSequences[i].length; j++) {
                        if (j != 0) expected.append(' ');
                        expected.append(tokenImage[expectedTokenSequences[i][j]]);
                    }
                }
                tokenErrDesc = "Encountered \"";
                Token tok = currentToken.next;
                for (int i = 0; i < maxSize; i++) {
                    if (i != 0) tokenErrDesc += " ";
                    if (tok.kind == 0) {
                        tokenErrDesc += tokenImage[0];
                        break;
                    }
                    tokenErrDesc += add_escapes(tok.image);
                    tok = tok.next;
                }
                tokenErrDesc += "\", but ";

                if (expectedTokenSequences.length == 1) {
                    tokenErrDesc += "was expecting:" + eol;
                } else {
                    tokenErrDesc += "was expecting one of:" + eol;
                }
                tokenErrDesc += expected;
            }
        } else {
            tokenErrDesc = null;
        }
        return tokenErrDesc;
    }

    private String getCustomTokenErrorDescription() {
        final Token nextToken = currentToken.next;
        final int kind = nextToken.kind;
        if (kind == EOF) {
            for (int i = 0; i < expectedTokenSequences.length; i++) {
                int[] sequence = expectedTokenSequences[i];
                String name;
                switch (sequence[0]) {
                case END_FOREACH :
                    name = "#foreach";
                    break;
                case END_LIST :
                    name = "#list";
                    break;
                case END_SWITCH :
                    name = "#switch";
                    break;
                case END_IF :
                    name = "#if";
                    break;
                case END_COMPRESS :
                    name = "#compress";
                    break;
                case END_MACRO :
                case END_FUNCTION :
                    // It gives [..., [END_FUNCTION, ...], [END_MACRO, ...], ...] for both. 
                    name = "#macro or #function";
                    break;
                case END_TRANSFORM :
                    name = "#transform";
                    break;
                case END_ESCAPE :
                    name = "#escape";
                    break;
                case END_NOESCAPE :
                    name = "#noescape";
                    break;
                case END_ASSIGN:
                    name = "#assign";
                    break;
                case END_LOCAL:
                    name = "#local";
                    break;
                case END_GLOBAL:
                    name = "#global";
                    break;
                case END_ATTEMPT:
                    name = "#attempt";
                    break;
                case CLOSE_BRACE:
                    name = "{";
                    break;
                case CLOSE_BRACKET:
                    name = "[";
                    break;
                case CLOSE_PAREN:
                    name = "(";
                    break;
                case UNIFIED_CALL_END:
                    name = "@...";
                    break;
                default:
                    name = null;
                }
                if (name != null) {
                    if (!name.startsWith("#") && !name.startsWith("@")) name = StringUtil.jQuote(name);
                    return "Unclosed " + name + " when the end of the file was reached.";
                }
            }
            return "Unexpected end of file reached.";
        } else if (kind == END_IF || kind == ELSE_IF || kind == ELSE) {
            return "Unexpected directive, "
                    + StringUtil.jQuote(nextToken)
                    + ". Check whether you have a valid #if-#elseif-#else structure.";
        }
        return null;
    }

    /**
     * Used to convert raw characters to their escaped version
     * when these raw version cannot be used as part of an ASCII
     * string literal.
     */
    protected String add_escapes(String str) {
        StringBuffer retval = new StringBuffer();
        char ch;
        for (int i = 0; i < str.length(); i++) {
            switch (str.charAt(i))
            {
            case 0 :
                continue;
            case '\b':
                retval.append("\\b");
                continue;
            case '\t':
                retval.append("\\t");
                continue;
            case '\n':
                retval.append("\\n");
                continue;
            case '\f':
                retval.append("\\f");
                continue;
            case '\r':
                retval.append("\\r");
                continue;
            case '\"':
                retval.append("\\\"");
                continue;
            case '\'':
                retval.append("\\\'");
                continue;
            case '\\':
                retval.append("\\\\");
                continue;
            default:
                if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
                    String s = "0000" + Integer.toString(ch, 16);
                    retval.append("\\u" + s.substring(s.length() - 4, s.length()));
                } else {
                    retval.append(ch);
                }
                continue;
            }
        }
        return retval.toString();
    }

}
