from sys import excepthook
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
import numpy as np


FLOAT_PARAMETER = ["tau_ms", "c_pf", "t_ref_ms", "v_reset_mv", "v_thresh_mv", "tau_ex_ms", "tau_in_ms", "h_ms"]

U8_PARAMETER = ["weightFracExc", "weightFracInh", "syncsPerTimeStep", "timestepLimit", "numberNeurons"]

Others = ["Boards"]

def validate_settings(number, keyword):
    if not number and keyword not in Others:
        raise ValidationError(_("Parameters should not be empty!"), params={"number": number},)

    if keyword in FLOAT_PARAMETER:
        validate_float(number)
    elif keyword in U8_PARAMETER:
        validate_u8_number
    elif keyword in Others:
        return
    else:
        raise ValidationError(_("Too many parameters were send!"))

def validate_float(number):
    if not number:
        raise ValidationError(_("Number should not be empty!"))
    
    try:
        float(number)
    except ValueError:
        raise ValidationError(_("No a valid number was passed!"))

def validate_u8_number(number):
    if not number:
        raise ValidationError(_("Number should not be empty!"))
    
    try:
        num = int(number)
        #if (num<0 or num > 255):
        if(num<0 or num > 100000000):
            raise ValidationError(_("{} must be positiv and smaller than 255.".format(U8_PARAMETER)))
    except ValueError:
        raise ValidationError(_("Not a valid number was passed!"))


def validate_request_data(data):
    parameter_list = FLOAT_PARAMETER + U8_PARAMETER + Others
    if len(parameter_list) == len(data):
        for element in data:
            if element not in parameter_list:
                raise ValidationError(_("One Parameter is not valid!"))
    else:
        print(len(data))
        raise ValidationError(_("The amount of parameters is not valid."))


def validate_start_message(message):
    if len(message) == 5:
        if message == "start":
            return
    raise ValidationError(_("The start is corrupted"));

def validate_selected_boards(boards, BOARDS_LIST):
    if len(boards) == 0:
        raise ValidationError(_("No board is selected."))

    first_board = boards[0]
    last_board = boards[-1]

    for index, row in enumerate(BOARDS_LIST):
        if first_board in row:
            
            for j, element in enumerate(row):
                if element == first_board:
                    top_left_corner = (index, j)

        if last_board in row:
            for j, element in enumerate(row):
                if element == last_board:
                    bottom_right_corner = (index, j)

    num_of_elements = (bottom_right_corner[0]+1-top_left_corner[0])*(bottom_right_corner[1]+1-top_left_corner[1])
    if(num_of_elements	!= len(boards)):
        raise ValidationError(_("The selected boards do not form a rectangle."))

    boards_list = np.array(BOARDS_LIST)

    sub_boards_list = boards_list[top_left_corner[0]:bottom_right_corner[0]+1, top_left_corner[1]:bottom_right_corner[1]+1]
    
    for row in sub_boards_list:
        for element in row:
            if element not in boards:
                raise ValidationError(_("The selected boards do not form a rectangle."))
    
def validate_board_name(name):
    if len(name) != 2:
        raise ValidationError(_("This is no board name"));
    