/*!
  \file    DBMSrvMsg_Error.hpp
  \author  MarcW, TiloH
  \ingroup error, warning and information message handling for DBM Server
  \brief   declaration of a class for error messages

    ========== licence begin  GPL
    Copyright (c) 2004-2006 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program 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 for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
*/


#if !defined(DBMSrvMsg_Error_hpp)
#define DBMSrvMsg_Error_hpp


#include "SAPDBCommon/ErrorsAndMessages/SAPDBErr_MessageList.hpp"
#include "DBM/Srv/Message/DBMSrvMsg_Base.hpp"


/*!
    @brief error message

    A new error message is defined as follows:
    * create a new entry at the end of the enum DBMSrvMsg_Error::ID
    * create a new entry in the static array m_ErrorTextArray,
      that has the new ID as key
*/
class DBMSrvMsg_Error : public SAPDBErr_MessageList, public DBMSrvMsg_Base {
public:
    /*! @brief error IDs */
    enum ErrorID {
        NOBRAIN,        /*!< test without parameter */
        NOBEER,         /*!< test with one parameter */
        NODBMLOGGER,    /*!< the DBM logger could not be initialized */
        DBISDROPPED,    /*!< the database is dropped, hence no commands can be executed */
        IS_NO_OPTION,   /*!< a command does not have a certain option */
        FILECHK,        /*!< error checking a file */
        FILEDEL,        /*!< error deleting a file */
        SHMNOINFOFILE,  /*!< shared memory no info file found */
        SHMNODATAFILE,  /*!< shared memory no data file found */
        SHMFILEPERM,    /*!< shared memory no necessary file permissions */
        SHMNOTAVAILABLE,/*!< shared memory is not available (message is for higher levels) */
        BHIST_EXT_INVALID_LINE,/*!< the line supplied is no valid line for external backup history dbm.ebf*/
        BHIST_EXT_OPEN, /*!< external backup history dbm.ebf could not be opened */
        BHIST_EXT_WRITE,/*!< external backup history dbm.ebf could not be written */
        MEMORY,         /*!< required memory could not be allocated */

        WRONGDBSTATE=(217-158),
        DBSTATENEEDED1=(218-158),

        SETENV=(234-158),

        FORMAT_SEPARATORMISSING=(238-158),

        MEFDIRTY               =(301-158),
        FORMAT_DELIMISS        =(302-158),

        COMM_PACKTOOSMALL      =(312-158),
        BHIST_TOOMUCHDATA      =(313-158),



        /* insert new ID one line above */
        LAST_ID         /*!< !!!! this must remain the last enum defined for DBMSrvMsg_Error::ID and must not be used as error ID !!!! */
    };

    /*! @brief default constructor
    
        use this constructor to create a empty error list */
    DBMSrvMsg_Error();

    /*!
        @brief constructor

        Takes an error ID, the numberr of arguments that shall be inserted into
        the error text that is assosciated with the ID and the arguments themselves. Up
        to 10 arguments can be specified.
        @param aErrorID [IN] ID of the error message
        @param arg0 [IN] string argument 0
        @param arg1 [IN] string argument 1
        @param arg2 [IN] string argument 2
        @param arg3 [IN] string argument 3
        @param arg4 [IN] string argument 4
        @param arg5 [IN] string argument 5
        @param arg6 [IN] string argument 6
        @param arg7 [IN] string argument 7
        @param arg8 [IN] string argument 8
        @param arg9 [IN] string argument 9
    */
    DBMSrvMsg_Error(
        const DBMSrvMsg_Error::ErrorID aErrorID,
        const char* const arg0 = NULL,
        const char* const arg1 = NULL,
        const char* const arg2 = NULL,
        const char* const arg3 = NULL,
        const char* const arg4 = NULL,
        const char* const arg5 = NULL,
        const char* const arg6 = NULL,
        const char* const arg7 = NULL,
        const char* const arg8 = NULL,
        const char* const arg9 = NULL);

    /*! @brief copy constructor */
    DBMSrvMsg_Error( DBMSrvMsg_Error const &aError )
         : SAPDBErr_MessageList(aError) {}

    /*! @brief empty destructor */
    virtual ~DBMSrvMsg_Error() {}

    /*! @brief function returning the DBM Server error ID of a error
        \return the error ID of the first message of a last
        \TODO return the error ID of the last message of the list (newest message) */
    /*const DBMSrvMsg_Error::ErrorID getErrorID() const {
        return DBMSrvMsg_Error::ErrorID(SAPDBErr_MessageList::ID() + 25000 - 158);
    }*/

    /*! @brief for easy addition of errors */
    DBMSrvMsg_Error operator+ (const SAPDBErr_MessageList& otherList ) const;

    /*!
        @brief comparing to a DBMSrvMsg_Error::ErrorID

        The range of the ErrorID (0, 1, ...) is converted to the range of
        DBM error numbers (-24999, -24998, ...). In the calling code: in front of the
        == operator there is the DBMSrvMsg_Error, behind it is the ErrorID.

        @param aErrid [IN] the error ID to compare this DBMSrvMsg_Error to
        @return true if the ID in this object equals aErrid, false otherwise
    */
    bool operator==(const DBMSrvMsg_Error::ErrorID& aErrid) const {
       return (SAPDBErr_MessageList::ID() + 25000 - 158) == int(aErrid);
    }
};


/*!
    @brief comparing a DBMSrvMsg_Error::ErrorID to a SAPDBErr_MessageList

    The range of the ErrorID (0, 1, ...) is converted to the range of
    DBM error numbers (-25000, -24999, ...). In the calling code: in front of
    the == operator there is the ErrorID, behind it is the SAPDBErr_MessageList.

    @param aErrid [IN] the error ID to compare the message list to 
    @param aMsgList [IN] the message list
    @return true if the id of the message list equals aErrid, false otherwise

*/
bool operator==(const DBMSrvMsg_Error::ErrorID & aErrid, const SAPDBErr_MessageList& aMsgList);

/*! \brief comparing a DBMSrvMsg_Error::ErrorID to a SAPDB_UInt4 or tcn00_Error

    This operator causes an ambiguity, if Microsofts's compiler is used, so
    in praxis you will not be able to use it :( (if this changes some day, the
    operator must be implemented too. Hopefully we have eliminated tcn00_Error
    until then)

    The range of the ErrorID (0, 1, ...) is converted to the range of
    DBM error numbers (-24999, -24998, ...). In the calling code: in front of
    the == operator there is the ErrorID, behind it is the SAPDB_UInt4.

    \param aErrid [IN] the error ID as ErrorID  
    \param aError [IN] the integer
    \return true if aError equals aErrid, false otherwise */
bool operator==(const DBMSrvMsg_Error::ErrorID aErrid, const SAPDB_UInt4 aError);

/*! \brief comparing a DBMSrvMsg_Error::ErrorID to another DBMSrvMsg_Error::ErrorID

    This operator causes an ambiguity, if Microsofts's compiler for IA64 is used, so
    in praxis you will not be able to use it :( (if this changes some day, the
    operator must be implemented too.)

    The range of the ErrorID (0, 1, ...) is converted to the range of
    DBM error numbers (-24999, -24998, ...). In the calling code: in front of
    the == operator there is the ErrorID, behind it is another ErrorID.

    \param aErrid      [IN] one error ID as ErrorID 
    \param secondErrid [IN] a second error ID as ErrorID
    \return true if the aErrid equals secondErrid, false otherwise */
bool operator==(const DBMSrvMsg_Error::ErrorID aErrid, const DBMSrvMsg_Error::ErrorID secondErrid);


/*!
    @brief DBM error message definition

    an error message consists of an ID of class DBMSrvMsg_Error::ID and a text that
    can contain printf formatting instructions.
*/
class DBMSrvMsg_ErrorText {
public:
    /*! default constructor */
    DBMSrvMsg_ErrorText() {}

    /*!
        @brief constructor

        @param aID [IN] the error's ID
        @param aText [IN] the message's text
    */
    DBMSrvMsg_ErrorText(const DBMSrvMsg_Error::ErrorID aID, const char* aText)
        : m_ID(aID),
          m_Text(aText) {}
    
    /*! @brief return the message's ID */
    const DBMSrvMsg_Error::ErrorID getErrorID() const {return m_ID;}

    /*! @brief return the message's text */
    const char* getText() const {return m_Text;}

private:
    DBMSrvMsg_Error::ErrorID m_ID;
    const char * m_Text;
};

/*!
    @brief smart array to avoid long startup time of DBM server
*/
class DBMSrvMsg_ErrorTextArray {
public:
    /*!
        @brief return error text object with passed ID

        Note that there is no check of the rqeuested ID is valid!
        @param aID [IN] ID of requested error text object
        @return requested error text object
    */
    static const DBMSrvMsg_ErrorText& getErrorText(const DBMSrvMsg_Error::ErrorID aID);

    /*! @brief you never know... */
    virtual ~DBMSrvMsg_ErrorTextArray() {}

private:
    DBMSrvMsg_ErrorTextArray() {}

    static void initArray();
    static bool m_IsInitialized;
    static DBMSrvMsg_ErrorText m_ErrorTextArray[DBMSrvMsg_Error::LAST_ID+1];
};

#endif //DBMSrvMsg_Error_hpp
