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} -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 = "./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")
