// Copyright 2020 Siemens Digital Industries Software
// ==================================================
// Copyright 2013.
// Siemens Product Lifecycle Management Software Inc.
// All Rights Reserved.
// ==================================================
// Copyright 2020 Siemens Digital Industries Software

/**
    @file
    This file contains the declarations of the IFail class in module libbase_utils.
    IFail is a throwable class which stacks an error (or uses the last one on the stack).
*/

/**  */

#ifndef TEAMCENTER_BASE_UTILS_IFAIL_HXX
#define TEAMCENTER_BASE_UTILS_IFAIL_HXX

#include <vector>
#include <string>
#include <ostream>

#include <base_utils/libbase_utils_exports.h>

class ResultStatus;
class ResultCheck;

/**
    @brief A throwable class used to store errors on the error stack.

    @code
    try
    {
        [...]
        int retCode = POM_get_user( &userName, &vUserTag );
        if( retCode!=ITK_ok || vUserTag == NULLTAG )
        {
            throw IFail(TIE_null_attribute, ValidationResultClassName, VALIDATION_USER);
        }
        [...]
    }
    catch ( const IFail& ifail )
    {
        [...]
    }
    @endcode
*/
class BASE_UTILS_API IFail
{
public:
    /**
        Default constructor.
        <br>It uses the last error stored on the error stack.
    */
    IFail();

    /**
        Constructor of an instance with a provided error code and its associated parameters.

        @param[in] ifail The error code
        @param[in] s1    Substitution for the parameter 1 in the displayable error message.
        @param[in] s2    Substitution for the parameter 2 in the displayable error message.
        @param[in] s3    Substitution for the parameter 3 in the displayable error message.
        @param[in] s4    Substitution for the parameter 4 in the displayable error message.
        @param[in] s5    Substitution for the parameter 5 in the displayable error message.
        @param[in] s6    Substitution for the parameter 6 in the displayable error message.
        @param[in] s7    Substitution for the parameter 7 in the displayable error message.
    */
    IFail( int ifail,
           const char *s1=0, const char *s2=0, const char *s3=0,
           const char *s4=0, const char *s5=0, const char *s6=0,
           const char *s7=0 ); /*  */

    /**
       Destructor
    */
    ~IFail();

    /**
        Retrieves the associated error code.
    */
    int ifail() const;

    /**
        Retrieves the associated error code.
    */
    operator int() const; /*  */

    /**
     * Retrieves the contents of the error stack, and then clears the error stack.
     * <br>The older error is at the last position of the arrays for this method.
     *
     * @note The errors are returned in reverse order compared to a call to the EMH_ask_errors.
     * @param[in] errorCodes    The list of error codes on the error stack
     * @param[in] severities    The list of severities for each of the errors (#EMH_severity_error, #EMH_severity_warning, or #EMH_severity_information).
     * @param[in] errorMessages The displayable error message for each error.
     */
    void getAndClearErrorStack( std::vector<int>&         errorCodes,
                                std::vector<int>&         severities,
                                std::vector<std::string>& errorMessages );

    /**
     * Returns a localized message in which all error code parameters have been substituted.
     */
    const std::string & getMessage() const;

private:
    /** Private constructor */
    IFail( bool storeError, int ifail );

    /** The error code */
    int m_ifail;
    std::string m_message;

    friend class ResultStatus;
    friend class ResultCheck;
};

/**
    Prints the IFail object on the given stream.
    <br>The print is in the following format:
    @code
    IFail:
     [infod|warning|error|user] &lt;error_code&gt;
         &lt;display_error_message&gt;
    @endcode

    @param[in] out   The output stream where the information is to be printed.
    @param[in] ifail The IFail instance to print.
*/
BASE_UTILS_API std::ostream& operator<<( std::ostream& out, const IFail& ifail );

#include <base_utils/libbase_utils_undef.h>

#endif
