"""Define the exception classes corresponding to MQI errors and errors
within this library.
"""

# Copyright (c) 2025 IBM Corporation and other Contributors. All Rights Reserved.
# Copyright (c) 2009-2024 Dariusz Suchojad. All Rights Reserved.

try:
    from typing import Any, Dict
except ImportError:
    pass

from ibmmq import CMQC, CMQSTRC

class Error(Exception):
    """ Base class for all exceptions from this library.
    """

# ################################################################################################################################

class MQMIError(Error):
    """ Exception class for MQI level errors: hold the MQRC and MQCC values
    """
    errStringDicts = (CMQSTRC.MQRC_DICT, CMQSTRC.MQRCCF_DICT)
    comp = CMQC.MQCC_OK
    reason = CMQC.MQRC_NONE

    def __init__(self, comp: int, reason: int, **kw: Dict[str, Any]):
        """ Construct the error object with MQI completion code 'comp' and reason code 'reason'.
        """
        self.comp, self.reason = comp, reason

        for k, v in kw.items():
            setattr(self, k, v)

    def __str__(self) -> str:
        return 'MQI Error. Comp %d, Reason %d: %s' % (self.comp, self.reason, self.error_as_string())

    def error_as_string(self) -> str:
        """ Return the exception object MQI warning/failed reason as its mnemonic string.
        """
        if self.comp == CMQC.MQCC_OK:
            return 'OK'

        if self.comp == CMQC.MQCC_WARNING:
            pfx = 'WARNING: '
        else:
            pfx = 'FAILED: '

        for d in MQMIError.errStringDicts:
            if self.reason in d:
                return pfx + d[self.reason]
        return pfx + 'Error code ' + str(self.reason) + ' not defined'

    errorAsString = error_as_string

# ################################################################################################################################

class PYIFError(Error):
    """ Exception class for errors generated by this library
    """
    def __init__(self, e: str):
        self.error = e

    def __str__(self) -> str:
        return 'PYIBMMQ Error: ' + str(self.error)
