package org.mozartoz.truffle.runtime;

import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;

@SuppressWarnings("serial")
public class OzException extends RuntimeException {

	static final Arity ERROR_ARITY = Arity.build("error", 1L, "debug");
	static final Arity SYSTEM_ARITY = Arity.build("system", 1L, "debug");
	static final Arity FAILURE_ARITY = Arity.build("failure", "debug");

	public static DynamicObject newError(Object error) {
		return OzRecord.buildRecord(ERROR_ARITY, error, Unit.INSTANCE);
	}

	public static DynamicObject newSystemError(Object error) {
		return OzRecord.buildRecord(SYSTEM_ARITY, error, Unit.INSTANCE);
	}

	public static DynamicObject newFailure() {
		return OzRecord.buildRecord(FAILURE_ARITY, Unit.INSTANCE);
	}

	private final Object data;

	public OzException(Node currentNode, String message) {
		this(currentNode, newError(message.intern()));
	}

	public OzException(Node currentNode, Object data) {
		super(data.toString());
		OzBacktrace backtrace = OzBacktrace.capture(currentNode);

		Object storedData = data;
		if (data instanceof DynamicObject) {
			DynamicObject dataRecord = (DynamicObject) data;
			boolean hasDebug = dataRecord.containsKey("debug");
			if (hasDebug && dataRecord.get("debug") == Unit.INSTANCE) {
				DynamicObject dataWithDebug = dataRecord.copy(dataRecord.getShape());
				dataWithDebug.getShape().getProperty("debug").setInternal(dataWithDebug, backtrace);
				storedData = dataWithDebug;
			}
		}

		this.data = storedData;
	}

	public Object getData() {
		return data;
	}

	public OzBacktrace getBacktrace() {
		Object debug = ((DynamicObject) data).get("debug");
		return (OzBacktrace) debug;
	}

}

@@ -222,20 +222,28 @@
 c final 
-Arit
+RecordFactor
 y ERROR_
@@ -275,32 +275,48 @@
 r%22, 1L, %22debug%22)
+.createFactory()
 ;%0A%09static final 
@@ -315,20 +315,28 @@
 c final 
-Arit
+RecordFactor
 y SYSTEM
@@ -378,16 +378,32 @@
 %22debug%22)
+.createFactory()
 ;%0A%09stati
@@ -410,20 +410,28 @@
 c final 
-Arit
+RecordFactor
 y FAILUR
@@ -471,16 +471,32 @@
 %22debug%22)
+.createFactory()
 ;%0A%0A%09publ
@@ -557,42 +557,30 @@
 urn 
-OzRecord.buildRecord(ERROR_ARITY, 
+ERROR_ARITY.newRecord(
 erro
@@ -671,37 +671,16 @@
 %09return 
-OzRecord.buildRecord(
 SYSTEM_A
@@ -683,18 +683,27 @@
 EM_ARITY
-, 
+.newRecord(
 error, U
@@ -778,29 +778,8 @@
 urn 
-OzRecord.buildRecord(
 FAIL
@@ -787,18 +787,27 @@
 RE_ARITY
-, 
+.newRecord(
 Unit.INS

Use Record factories in OzException