#pragma once
#include "Exception.h"
#include "SrcPos.h"

namespace storm {
	STORM_PKG(core);

	/**
	 * Assertion exception, thrown when STORM_ASSERT() or STORM_FAIL() is used in the codebase.
	 */
	class EXCEPTION_EXPORT AssertError : public RuntimeError {
		STORM_EXCEPTION;
	public:
		// Create an exception based on file + line convention (from C++ usually).
		STORM_CTOR AssertError(Str *file, Nat line, MAYBE(Str *) expr, MAYBE(Str *) message);

		// Create an exception based on a Storm-based SrcPos.
		STORM_CTOR AssertError(SrcPos pos, MAYBE(Str *) expr, MAYBE(Str *) message);

		// Generate a message.
		virtual void STORM_FN message(StrBuf *to) const;

		// Get the expression.
		MAYBE(Str *) STORM_FN expression() const { return expr; }

		// Get the message passed to assert.
		MAYBE(Str *) STORM_FN assertMessage() const { return msg; }

		// Get the source position. Might be empty if the assertion is from C++.
		SrcPos STORM_FN position() const { return pos; }

	private:
		// File + line representation.
		MAYBE(Str *) file;
		Nat line;

		// SrcPos representation.
		SrcPos pos;

		// Failing expression, if any.
		MAYBE(Str *) expr;

		// Message, if any.
		MAYBE(Str *) msg;
	};

}
