/*
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#ifndef _LEAN_EXCEPTION_H
#define _LEAN_EXCEPTION_H

#ifdef __cplusplus
extern "C" {
#endif

LEAN_DEFINE_TYPE(lean_exception);

/** \brief Delete an exception object allocated by Lean.
    This is a NOOP if \c e is null.
*/
void lean_exception_del(lean_exception e);

/** \brief Return basic string/message describing the exception.
    \remark The string must be deallocated using #lean_string_del.

    \remark After we define the Lean environment object, we can
    provide richer messages.

    \remark The result is null if the operation failed or \c e is null.
*/
char const * lean_exception_get_message(lean_exception e);

/** \brief Return basic string/message describing the exception.
    \remark The string must be deallocated using #lean_string_del.
    This function is similar to #lean_exception_get_message, but produces
    more information if available.
*/
char const * lean_exception_get_detailed_message(lean_exception e);

/** \brief Exceptions and errors signed by the Lean API.
    The first four (LEAN_NULL_EXCEPTION, LEAN_SYSTEM_EXCEPTION, LEAN_OUT_OF_MEMORY, LEAN_INTERRUPTED)
    are considered to be low-level exceptions.
    In principle, any procedure that has the argument <tt>lean_exception * ex</tt> may return one
    of them.
    The remaining ones can be viewed as "real" (or high-level) exceptions, and
    we document the procedures that may throw them.
*/
typedef enum {
    LEAN_NULL_EXCEPTION,    // null (aka there is no exception)
    LEAN_SYSTEM_EXCEPTION,  // exception generated by the C++ runtime
    LEAN_OUT_OF_MEMORY,     // out of memory exception
    LEAN_INTERRUPTED,       // execution was interrupted by user request
    LEAN_KERNEL_EXCEPTION,  // type checking error
    LEAN_PARSER_EXCEPTION,  // parser exception
    LEAN_OTHER_EXCEPTION    // other (TODO) lean exceptions
} lean_exception_kind;

/** \brief Return the kind of the given exception. */
lean_exception_kind lean_exception_get_kind(lean_exception e);

#ifdef __cplusplus
};
#endif
#endif
