from subprocess import check_output, STDOUT
import re
from pathlib import Path
import time

SOURCE_PATH = Path.cwd().parents[2]
OUTPUT_PATH = SOURCE_PATH / "output"

def init_cluster_for_simulation(selected_boards: list, surrounding_boards: list):
    ret = []

    str_selected_boards = " ".join(selected_boards)
    str_surrounding_boards = " ".join(surrounding_boards)

    command = " ".join(["cd", str(SOURCE_PATH), ";", "./fpga.sh --targets", str_selected_boards, str_surrounding_boards, "--program"])

    time_start = time.time()
    print("Run command: {}".format(command))
    #ret.append(re.sub("\033[^\033t]*m", "",(check_output([command], stderr=STDOUT, shell=True)).decode("utf-8")))
    print("Reset-Boards Time: {}".format(time.time() - time_start))

    command = " ".join(["cd", str(SOURCE_PATH), ";", "./fpga.sh --targets", str_selected_boards, "--upload embedded"])

    time_start = time.time()
    print("Run command: {}".format(command))
    #ret.append(re.sub("\033[^\033t]*m", "", (check_output([command], stderr=STDOUT, shell=True)).decode("utf-8")))
    print("Upload Time: {}".format(time.time() - time_start))

    return ret

def start_simulation(main_board: str, number_of_timesteps: int, number_of_neurons: int):
    ret = ""

    command = " ".join(["cd", str(SOURCE_PATH),";", "export TARGET="+main_board, ";", "./sim.sh", number_of_timesteps, "src/sw/examples/n_rand_neurons.py --neurons", number_of_neurons, "--init"])

    time_start = time.time()
    print("Start Simulation: {}".format(command))
    #ret = re.sub("\033[^\033t]*m", "", (check_output([command], stderr=STDOUT, shell=True)).decode("utf-8"))
    print("Simulation Time: {}".format(time.time() - time_start))

    command = " ".join(["cd", str(SOURCE_PATH),";", "export TARGET="+main_board, ";", "./src/sw/examples/transferSpikes.sh"])
    time_start = time.time()
    check_output([command], stderr=STDOUT, shell=True)
    print("Load-Output Time: {}".format(time.time() - time_start))

    return ret

def restart_simulation(main_board: str, number_of_timesteps: int):
    ret = ""
    command = " ".join(["cd", str(SOURCE_PATH),";", "export TARGET="+main_board, ";", "./sim.sh", number_of_timesteps, "src/sw/examples/n_rand_neurons.py"])

    time_start = time.time()
    print("Restart Simulation: {}".format(command))
    #ret = re.sub("\033[^\033t]*m", "", (check_output([command], stderr=STDOUT, shell=True)).decode("utf-8"))
    print("Restart-Simulation Time: {}".format(time.time() - time_start))

    command = " ".join(["cd", str(SOURCE_PATH),";", "export TARGET="+main_board, ";", "./src/sw/examples/transferSpikes.sh"])
    time_start = time.time()
    check_output([command], stderr=STDOUT, shell=True)
    print("Load-Output Time: {}".format(time.time() - time_start))

    return ret

def get_simulation_info(main_board: str):
    ret = ""
    command = " ".join(["cd", str(SOURCE_PATH), ";", "export TARGET="+main_board, ";", "./run.sh --node 255 255 info"])

    time_start = time.time()
    print("Run command: {}".format(command))
    #ret = re.sub("\033[^\033t]*m", "", (check_output([command], stderr=STDOUT, shell=True)).decode("utf-8"))
    print("Simulation Info Time: {}".format(time.time() - time_start))

    return ret

def read_communication_informations(data: str)->dict:
    ret = {}
    data_list = data.splitlines()
    for line in data_list:
        if "info from" in line.casefold():
            node = line.split("(")[1].split(")")[0].split("|")
            ret.update({" ".join(node):{}})
        elif "neighbour" in line.casefold():
            communication_partner = line.split("(")[1].split(")")[0].split("|")
            if communication_partner[0] == "255" or communication_partner[1] == "255":
                continue
            infos = [int(info) for info in line.split(")")[1].replace(" ", "").split(",") if info != ""]
            if len(infos) < 4:
                continue
            ret[" ".join(node)].update({" ".join(communication_partner): infos})
    return ret

def read_simulation_information(data: str)->dict:
    ret = {}
    data_list = data.splitlines()
    for line in data_list:
        if "in total" in line.casefold():
            #line = line.replace("[49m[0m[45m", "").replace("[49m[0m", "")
            numbers = [int(temp_str) for temp_str in line.split(" ") if temp_str.isdigit()]
            ret.update({"timesteps": numbers[-1]})
        elif "since last" in line.casefold():
            #line = line.replace("[49m[0m[45m", "").replace("[49m[0m", "")
            number = line.split(" ")[4]
            ret.update({"number_of_spikes": int(number)})
        elif "a=" in line.casefold():
            #line = line.replace("[49m[0m[45m", "").replace("[49m[0m", "")
            real_time_factor = line.split(" ")[-1]
            ret.update({"real_time_factor": float(real_time_factor)})
    return ret

