/*
 * 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.internal.objects;

import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import jdk.nashorn.api.scripting.NashornException;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;

/**
 * ECMA 15.11 Error Objects
 */
@ScriptClass("Error")
public final class NativeError extends ScriptObject {

    static final MethodHandle GET_COLUMNNUMBER = findOwnMH("getColumnNumber", Object.class, Object.class);
    static final MethodHandle SET_COLUMNNUMBER = findOwnMH("setColumnNumber", Object.class, Object.class, Object.class);
    static final MethodHandle GET_LINENUMBER   = findOwnMH("getLineNumber", Object.class, Object.class);
    static final MethodHandle SET_LINENUMBER   = findOwnMH("setLineNumber", Object.class, Object.class, Object.class);
    static final MethodHandle GET_FILENAME     = findOwnMH("getFileName", Object.class, Object.class);
    static final MethodHandle SET_FILENAME     = findOwnMH("setFileName", Object.class, Object.class, Object.class);
    static final MethodHandle GET_STACK        = findOwnMH("getStack", Object.class, Object.class);
    static final MethodHandle SET_STACK        = findOwnMH("setStack", Object.class, Object.class, Object.class);

    // message property name
    static final String MESSAGE = "message";
    // name property name
    static final String NAME = "name";
    // stack property name
    static final String STACK = "__stack__";
    // lineNumber property name
    static final String LINENUMBER = "__lineNumber__";
    // columnNumber property name
    static final String COLUMNNUMBER = "__columnNumber__";
    // fileName property name
    static final String FILENAME = "__fileName__";

    /** Message property name */
    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
    public Object instMessage;

    /** ECMA 15.11.4.2 Error.prototype.name */
    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
    public Object name;

    /** ECMA 15.11.4.3 Error.prototype.message */
    @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
    public Object message;

    /** Nashorn extension: underlying exception */
    @Property(attributes = Attribute.NOT_ENUMERABLE)
    public Object nashornException;

    // initialized by nasgen
    private static PropertyMap $nasgenmap$;

    @SuppressWarnings("LeakingThisInConstructor")
    private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
        super(proto, map);
        if (msg != UNDEFINED) {
            this.instMessage = JSType.toString(msg);
        } else {
            this.delete(NativeError.MESSAGE, false);
        }
        initException(this);
    }

    NativeError(final Object msg, final Global global) {
        this(msg, global.getErrorPrototype(), $nasgenmap$);
    }

    private NativeError(final Object msg) {
        this(msg, Global.instance());
    }

    @Override
    public String getClassName() {
        return "Error";
    }

    /**
     * ECMA 15.11.2 The Error Constructor
     *
     * @param newObj true if this is being instantiated with a new
     * @param self   self reference
     * @param msg    error message
     *
     * @return NativeError instance
     */
    @Constructor
    public static NativeError constructor(final boolean newObj, final Object self, final Object msg) {
        return new NativeError(msg);
    }

    // This is called NativeError, NativeTypeError etc. to
    // associate a ECMAException with the ECMA Error object.
    @SuppressWarnings("unused")
    static void initException(final ScriptObject self) {
        // ECMAException constructor has side effects
        new ECMAException(self, null);
    }

    /**
     * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
     *
     * @param self self reference
     * @param errorObj the error object
     * @return undefined
     */
    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
    public static Object captureStackTrace(final Object self, final Object errorObj) {
        final ScriptObject sobj = Global.checkObject(errorObj);
        initException(sobj);
        sobj.delete(STACK, false);
        if (! sobj.has("stack")) {
            final ScriptFunction getStack = ScriptFunction.createBuiltin("getStack", GET_STACK);
            final ScriptFunction setStack = ScriptFunction.createBuiltin("setStack", SET_STACK);
            sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
        }
        return UNDEFINED;
    }

    /**
     * Nashorn extension: Error.dumpStack
     * dumps the stack of the current thread.
     *
     * @param self self reference
     *
     * @return undefined
     */
    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
    public static Object dumpStack(final Object self) {
        Thread.dumpStack();
        return UNDEFINED;
    }

    /**
     * Nashorn extension: Error.prototype.printStackTrace
     * prints stack trace associated with the exception (if available).
     * to the standard error stream.
     *
     * @param self self reference
     *
     * @return result of {@link ECMAException#printStackTrace(ScriptObject)}, which is typically undefined
     */
    @Function(attributes = Attribute.NOT_ENUMERABLE)
    public static Object printStackTrace(final Object self) {
        return ECMAException.printStackTrace(Global.checkObject(self));
    }

    /**
     * Nashorn extension: Error.prototype.getStackTrace()
     * "stack" property is an array typed value containing {@link StackTraceElement}
     * objects of JavaScript stack frames.
     *
     * @param self  self reference
     *
     * @return      stack trace as a script array.
     */
    @Function(attributes = Attribute.NOT_ENUMERABLE)
    public static Object getStackTrace(final Object self) {
        final ScriptObject sobj = Global.checkObject(self);
        final Object exception = ECMAException.getException(sobj);
        Object[] res;
        if (exception instanceof Throwable) {
            res = NashornException.getScriptFrames((Throwable)exception);
        } else {
            res = ScriptRuntime.EMPTY_ARRAY;
        }

        return new NativeArray(res);
    }

    /**
     * Nashorn extension: Error.prototype.lineNumber
     *
     * @param self self reference
     *
     * @return line number from which error was thrown
     */
    public static Object getLineNumber(final Object self) {
        final ScriptObject sobj = Global.checkObject(self);
        return sobj.has(LINENUMBER) ? sobj.get(LINENUMBER) : ECMAException.getLineNumber(sobj);
    }

    /**
     * Nashorn extension: Error.prototype.lineNumber
     *
     * @param self  self reference
     * @param value value of line number
     *
     * @return value that was set
     */
    public static Object setLineNumber(final Object self, final Object value) {
        final ScriptObject sobj = Global.checkObject(self);
        if (sobj.hasOwnProperty(LINENUMBER)) {
            sobj.put(LINENUMBER, value, false);
        } else {
            sobj.addOwnProperty(LINENUMBER, Attribute.NOT_ENUMERABLE, value);
        }
        return value;
    }

    /**
     * Nashorn extension: Error.prototype.columnNumber
     *
     * @param self self reference
     *
     * @return column number from which error was thrown
     */
    public static Object getColumnNumber(final Object self) {
        final ScriptObject sobj = Global.checkObject(self);
        return sobj.has(COLUMNNUMBER) ? sobj.get(COLUMNNUMBER) : ECMAException.getColumnNumber((ScriptObject)self);
    }

    /**
     * Nashorn extension: Error.prototype.columnNumber
     *
     * @param self  self reference
     * @param value value of column number
     *
     * @return value that was set
     */
    public static Object setColumnNumber(final Object self, final Object value) {
        final ScriptObject sobj = Global.checkObject(self);
        if (sobj.hasOwnProperty(COLUMNNUMBER)) {
            sobj.put(COLUMNNUMBER, value, false);
        } else {
            sobj.addOwnProperty(COLUMNNUMBER, Attribute.NOT_ENUMERABLE, value);
        }
        return value;
    }

    /**
     * Nashorn extension: Error.prototype.fileName
     *
     * @param self self reference
     *
     * @return file name from which error was thrown
     */
    public static Object getFileName(final Object self) {
        final ScriptObject sobj = Global.checkObject(self);
        return sobj.has(FILENAME) ? sobj.get(FILENAME) : ECMAException.getFileName((ScriptObject)self);
    }

    /**
     * Nashorn extension: Error.prototype.fileName
     *
     * @param self  self reference
     * @param value value of file name
     *
     * @return value that was set
     */
    public static Object setFileName(final Object self, final Object value) {
        final ScriptObject sobj = Global.checkObject(self);
        if (sobj.hasOwnProperty(FILENAME)) {
            sobj.put(FILENAME, value, false);
        } else {
            sobj.addOwnProperty(FILENAME, Attribute.NOT_ENUMERABLE, value);
        }
        return value;
    }

    /**
     * Nashorn extension: Error.prototype.stack
     * "stack" property is a string typed value containing JavaScript stack frames.
     * Each frame information is separated bv "\n" character.
     *
     * @param self  self reference
     *
     * @return      value of "stack" property
     */
    public static Object getStack(final Object self) {
        final ScriptObject sobj = Global.checkObject(self);
        if (sobj.has(STACK)) {
            return sobj.get(STACK);
        }

        final Object exception = ECMAException.getException(sobj);
        if (exception instanceof Throwable) {
            final Object value = getScriptStackString(sobj, (Throwable)exception);
            if (sobj.hasOwnProperty(STACK)) {
                sobj.put(STACK, value, false);
            } else {
                sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value);
            }

            return value;
        }

        return UNDEFINED;
    }

    /**
     * Nashorn extension
     * Accessed from {@link Global} while setting up the Error.prototype
     *
     * @param self   self reference
     * @param value  value to set "stack" property to, must be {@code ScriptObject}
     *
     * @return value that was set
     */
    public static Object setStack(final Object self, final Object value) {
        final ScriptObject sobj = Global.checkObject(self);
        if (sobj.hasOwnProperty(STACK)) {
            sobj.put(STACK, value, false);
        } else {
            sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value);
        }
        return value;
    }

    /**
     * ECMA 15.11.4.4 Error.prototype.toString ( )
     *
     * @param self  self reference
     *
     * @return this NativeError as a string
     */
    @Function(attributes = Attribute.NOT_ENUMERABLE)
    public static Object toString(final Object self) {
        // Step 1 and 2 : check if 'self' is object it not throw TypeError
        final ScriptObject sobj = Global.checkObject(self);

        // Step 3 & 4 : get "name" and convert to String.
        // But if message is undefined make it "Error".
        Object name = sobj.get("name");
        if (name == UNDEFINED) {
            name = "Error";
        } else {
            name = JSType.toString(name);
        }

        // Steps 5, 6, & 7 : get "message" and convert to String.
        // if 'message' is undefined make it "" (empty String).
        Object msg = sobj.get("message");
        if (msg == UNDEFINED) {
            msg = "";
        } else {
            msg = JSType.toString(msg);
        }

        // Step 8 : if name is empty, return msg
        if (((String)name).isEmpty()) {
            return msg;
        }

        // Step 9 : if message is empty, return name
        if (((String)msg).isEmpty()) {
            return name;
        }
        // Step 10 : return name + ": " + msg
        return name + ": " + msg;
    }

    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
        return MH.findStatic(MethodHandles.lookup(), NativeError.class, name, MH.type(rtype, types));
    }

    private static String getScriptStackString(final ScriptObject sobj, final Throwable exp) {
        return JSType.toString(sobj) + "\n" + NashornException.getScriptStackString(exp);
    }
}
