/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.api.scripting;

import java.util.ArrayList;
import java.util.List;
import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.runtime.ECMAErrors;
import jdk.nashorn.internal.runtime.ScriptObject;

/**
 * This is base exception for all Nashorn exceptions. These originate from
 * user's ECMAScript code. Example: script parse errors, exceptions thrown from
 * scripts. Note that ScriptEngine methods like "eval", "invokeMethod",
 * "invokeFunction" will wrap this as ScriptException and throw it. But, there
 * are cases where user may need to access this exception (or implementation
 * defined subtype of this). For example, if java interface is implemented by a
 * script object or Java access to script object properties via java.util.Map
 * interface. In these cases, user code will get an instance of this or
 * implementation defined subclass.
 *
 * @since 1.8u40
 */
@jdk.Exported
@SuppressWarnings("serial")
public abstract class NashornException extends RuntimeException {
    // script file name
    private String fileName;
    // script line number
    private int line;
    // are the line and fileName unknown?
    private boolean lineAndFileNameUnknown;
    // script column number
    private int column;
    // underlying ECMA error object - lazily initialized
    private Object ecmaError;

    /**
     * Constructor
     *
     * @param msg       exception message
     * @param fileName  file name
     * @param line      line number
     * @param column    column number
     */
    protected NashornException(final String msg, final String fileName, final int line, final int column) {
        this(msg, null, fileName, line, column);
    }

    /**
     * Constructor
     *
     * @param msg       exception message
     * @param cause     exception cause
     * @param fileName  file name
     * @param line      line number
     * @param column    column number
     */
    protected NashornException(final String msg, final Throwable cause, final String fileName, final int line, final int column) {
        super(msg, cause == null ? null : cause);
        this.fileName = fileName;
        this.line = line;
        this.column = column;
    }

    /**
     * Constructor
     *
     * @param msg       exception message
     * @param cause     exception cause
     */
    protected NashornException(final String msg, final Throwable cause) {
        super(msg, cause == null ? null : cause);
        // Hard luck - no column number info
        this.column = -1;
        // We can retrieve the line number and file name from the stack trace if needed
        this.lineAndFileNameUnknown = true;
    }

    /**
     * Get the source file name for this {@code NashornException}
     *
     * @return the file name
     */
    public final String getFileName() {
        ensureLineAndFileName();
        return fileName;
    }

    /**
     * Set the source file name for this {@code NashornException}
     *
     * @param fileName the file name
     */
    public final void setFileName(final String fileName) {
        this.fileName = fileName;
        lineAndFileNameUnknown = false;
    }

    /**
     * Get the line number for this {@code NashornException}
     *
     * @return the line number
     */
    public final int getLineNumber() {
        ensureLineAndFileName();
        return line;
    }

    /**
     * Set the line number for this {@code NashornException}
     *
     * @param line the line number
     */
    public final void setLineNumber(final int line) {
        lineAndFileNameUnknown = false;
        this.line = line;
    }

    /**
     * Get the column for this {@code NashornException}
     *
     * @return the column number
     */
    public final int getColumnNumber() {
        return column;
    }

    /**
     * Set the column for this {@code NashornException}
     *
     * @param column the column number
     */
    public final void setColumnNumber(final int column) {
        this.column = column;
    }

    /**
     * Returns array javascript stack frames from the given exception object.
     *
     * @param exception exception from which stack frames are retrieved and filtered
     * @return array of javascript stack frames
     */
    public static StackTraceElement[] getScriptFrames(final Throwable exception) {
        final StackTraceElement[] frames = exception.getStackTrace();
        final List<StackTraceElement> filtered = new ArrayList<>();
        for (final StackTraceElement st : frames) {
            if (ECMAErrors.isScriptFrame(st)) {
                final String className = "<" + st.getFileName() + ">";
                String methodName = st.getMethodName();
                if (methodName.equals(CompilerConstants.PROGRAM.symbolName())) {
                    methodName = "<program>";
                }

                if (methodName.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName())) {
                    methodName = "<anonymous>";
                }

                filtered.add(new StackTraceElement(className, methodName,
                        st.getFileName(), st.getLineNumber()));
            }
        }
        return filtered.toArray(new StackTraceElement[filtered.size()]);
    }

    /**
     * Return a formatted script stack trace string with frames information separated by '\n'
     *
     * @param exception exception for which script stack string is returned
     * @return formatted stack trace string
     */
    public static String getScriptStackString(final Throwable exception) {
        final StringBuilder buf = new StringBuilder();
        final StackTraceElement[] frames = getScriptFrames(exception);
        for (final StackTraceElement st : frames) {
            buf.append("\tat ");
            buf.append(st.getMethodName());
            buf.append(" (");
            buf.append(st.getFileName());
            buf.append(':');
            buf.append(st.getLineNumber());
            buf.append(")\n");
        }
        final int len = buf.length();
        // remove trailing '\n'
        if (len > 0) {
            assert buf.charAt(len - 1) == '\n';
            buf.deleteCharAt(len - 1);
        }
        return buf.toString();
    }

    /**
     * Get the thrown object. Subclass responsibility
     * @return thrown object
     */
    protected Object getThrown() {
        return null;
    }

    /**
     * Initialization function for ECMA errors. Stores the error
     * in the ecmaError field of this class. It is only initialized
     * once, and then reused
     *
     * @param global the global
     * @return initialized exception
     */
    protected NashornException initEcmaError(final ScriptObject global) {
        if (ecmaError != null) {
            return this; // initialized already!
        }

        final Object thrown = getThrown();
        if (thrown instanceof ScriptObject) {
            setEcmaError(ScriptObjectMirror.wrap(thrown, global));
        } else {
            setEcmaError(thrown);
        }

        return this;
    }

    /**
     * Return the underlying ECMA error object, if available.
     *
     * @return underlying ECMA Error object's mirror or whatever was thrown
     *         from script such as a String, Number or a Boolean.
     */
    public Object getEcmaError() {
        return ecmaError;
    }

    /**
     * Return the underlying ECMA error object, if available.
     *
     * @param ecmaError underlying ECMA Error object's mirror or whatever was thrown
     *         from script such as a String, Number or a Boolean.
     */
    public void setEcmaError(final Object ecmaError) {
        this.ecmaError = ecmaError;
    }

    private void ensureLineAndFileName() {
        if (lineAndFileNameUnknown) {
            for (final StackTraceElement ste : getStackTrace()) {
                if (ECMAErrors.isScriptFrame(ste)) {
                    // Whatever here is compiled from JavaScript code
                    fileName = ste.getFileName();
                    line = ste.getLineNumber();
                    return;
                }
            }

            lineAndFileNameUnknown = false;
        }
    }
}
