# -*- coding: utf-8 -*-
"""
Created on Sun Mar 15 17:20:07 2020

@author: Sophie
"""

import ctypes

from neticapy import environ as envrn
from neticapy import enums
from neticapy.loaddll import Netica

checkerr_ = True

# Error numbers 6500 - 6599 

def _raise_netica_error(err_num, err_mesg, severity=None, category=None):
    """Raise NeticaError

    Creates an error message of the same form as NeticaError,
    and then raises NeticaError. This function currently doesn't


    May want to create a new error in Netica through NewError
    (or some other function) if NeticaPy is not throwing exceptions, 
    or if we want the dialogue box to appear in the application.
    """
    # Netica.NewError_ns.restype = ctypes.c_void_p
    # Netica.NewError_ns(ctypes.c_void_p(envrn.env), err_num, severity, 
    #                    ctypes.c_char_p(err_mesg.encode()))

    raise NeticaError((err_num, err_mesg))

class NeticaError(Exception):
    
    def __init__(self, report):
        """report can be a report cptr or a tuple containing the error number message

        If tuple, populates number and message properties

        If report, calls Netica.ErrorNumber_ns, Netica.ErrorMessage_ns,
        and enums.get_error_severity to set self.err_num, self.err_mesg, and
        self.severity. Clears all errors in Netica, then formats self.message
        with the correct error string.
        """
        if isinstance(report, tuple):
            if len(report) == 2:        # possibly extend to include severity or other attributes
                self.number = report[0]
                self.message = report[1]

        else:
            Netica.ErrorNumber_ns.restype = ctypes.c_int
            err_num = Netica.ErrorNumber_ns(ctypes.c_void_p(report))
            self.number = err_num

            Netica.ErrorMessage_ns.restype = ctypes.c_char_p
            err_mesg = Netica.ErrorMessage_ns(ctypes.c_void_p(report)).decode()
            self.message = err_mesg
                    
            Netica.ErrorSeverity_ns.restype = ctypes.c_int
            err_sever = Netica.ErrorSeverity_ns(ctypes.c_void_p(report))
            self.severity = enums.get_error_severity(err_sever)
                
            # May not want to clear XXX_ERR to force the developer to restart the
            # system when encountereing an internal error (from 6 to 5)      
            Netica.ClearErrors_ns.restype = None
            Netica.ClearErrors_ns(ctypes.c_void_p(envrn.env), 6)       
    
    def __str__(self):
        """Return the string set by __init__ in self.message
        """
        self.error_message = str("#" + str(self.number) + " - " + self.message)

        return self.error_message

def checkerr():
    if checkerr_:                 # User can turn off automatic error checking
        Netica.GetError_ns.restype = ctypes.c_void_p
        report = Netica.GetError_ns(ctypes.c_void_p(envrn.env), 5, None)

        if report:
            raise NeticaError(report)