import queue
import sys
import time
import subprocess
import threading
import logging
import datetime
import argparse
import os

from scripts.report.report import Report
from scripts.config.config import ConfigHandler
import scripts.utils.utils as utils

configuration_keys = ['adjustment_factor', 'utilization', 'density',
        'strategy', 'fanout', 'pdn_v', 'pdn_h', 'aspect_ratio']

parser = argparse.ArgumentParser(
        description="Regression test on designs")
parser.add_argument('--config', '-c', action='store', default='config',
                help="config file")
parser.add_argument('--regression', '-r', action='store', default=None,
                help="regression file")
parser.add_argument('--designs', '-d', nargs='+', default=['spm'],
                help="designs to run")
parser.add_argument('--tag', '-t', action='store', default='regression',
                help="tag the log file")
parser.add_argument('--threads', '-th', action='store', type=int, default=5,
                help="number of designs in parallel")
args = parser.parse_args()

regression = args.regression
tag = args.tag
designs = args.designs
num_workers = args.threads
config = args.config

report_file_name = "./logs/{tag}_{date}".format(tag=tag, date=datetime.datetime.now().strftime('%d_%m_%Y_%H_%M'))
log = logging.getLogger("log")
log_formatter = logging.Formatter('[%(asctime)s - %(levelname)5s] %(message)s')
handler1 = logging.FileHandler("{report_file_name}.log".format(report_file_name=report_file_name), 'w')
handler1.setFormatter(log_formatter)
log.addHandler(handler1)
handler2 = logging.StreamHandler()
handler2.setFormatter(log_formatter)
log.addHandler(handler2)
log.setLevel(logging.INFO)

report_log = logging.getLogger("report_log")
report_formatter = logging.Formatter('%(message)s')
report_handler = logging.FileHandler("{report_file_name}.rpt".format(report_file_name=report_file_name), 'w')
report_handler.setFormatter(report_formatter)
report_log.addHandler(report_handler)
report_log.setLevel(logging.INFO)

report_log.info(Report.get_header() + "," + ConfigHandler.get_header())

def run_design(designs_queue):
        while not designs_queue.empty():
                design, config, tag= designs_queue.get(timeout=3)  # 3s timeout
                run_path = utils.get_run_path(design=design, tag=tag)
                command = './flow.tcl -design {design} -tag {tag} -overwrite -disable_output -config {config}'.format(design=design,tag=tag, config=config)
                log.info('{design} {tag} running'.format(design=design, tag=tag))
                try:
                        subprocess.check_output(command.split(), stderr=subprocess.PIPE)
                except subprocess.CalledProcessError as e:
                        error_msg = e.stderr.decode(sys.getfilesystemencoding())
                        #print(error_msg)
                        log.error('{design} {tag} failed check {run_path}error.txt'.format(design=design, run_path=run_path, tag=tag))
                        report_log.error('{design} {tag} failed'.format(design=design, tag=tag))
                        with open(run_path + "error.txt", "w") as error_file:
                                error_file.write(error_msg)     
                        continue

                log.info('{design} {tag} finished\t Writing report..'.format(design=design, tag=tag))
                params = ConfigHandler.get_config(design, tag)

                report = Report(design, tag, params).get_report()
                report_log.info(report)

                with open(run_path + "final_report.txt", "w") as report_file:
                        report_file.write(Report.get_header() + ", " + ConfigHandler.get_header())
                        report_file.write("\n")
                        report_file.write(report)


#designs=["spm", "xtea", "zipdiv", "cordic", "md5", "y_huff", "picorv32a", "sha3", "des", "aes_core", "sha512", "sub86", "TEA"]
#designs=["aes_core", "sha512", "y_huff"]
print(designs)

que = queue.Queue()
total_runs = 0
if regression is not None:
    regression_file = os.path.join(os.getcwd(), regression)
    number_of_configs=0
    for design in designs:
        base_path = utils.get_design_path(design=design)
        base_config_path=base_path+"base_config.tcl"

        ConfigHandler.gen_base_config(design, base_config_path)
        gen_config_cmd="./scripts/config/generate_config.sh {base_config} {output_path} config_{tag} {regression_file}".format(
            base_config=base_config_path,
            output_path=base_path,
            tag=tag,
            regression_file=regression_file
            )

        number_of_configs = subprocess.check_output(gen_config_cmd.split())
        number_of_configs = int(number_of_configs.decode(sys.getdefaultencoding()))
        total_runs = total_runs + number_of_configs

        for i in range(number_of_configs):
            config_tag = "config_{tag}_{idx}".format(
                    tag=tag,
                    idx=i
                    )
            config_file = "{base_path}/{config_tag}".format(
                    base_path=base_path,
                    config_tag=config_tag,
                    )
            que.put((design, config_tag, config_tag))
else:
    for design in designs:
        default_config_tag = "config_{tag}".format(tag=tag)
        que.put((design, config, default_config_tag))
    

workers = []
for i in range(num_workers):
        workers.append(threading.Thread(target=run_design, args=(que,)))
        workers[i].start()

for i in range(num_workers):
        workers[i].join()
        print("Exiting thread", i)

log.info("Getting top results..")
best_result_cmd = "python3 ./scripts/report/get_best.py -i {input} -o {output}".format(
        input=report_handler.baseFilename,
        output=report_file_name + "_best.rpt"
        )
subprocess.check_output(best_result_cmd.split())
log.info("Done")
