import os
import subprocess
import sys
from shutil import copyfile
from ..utils.utils import *

class ConfigHandler():
#    def __init__(self, tag):
#        self.tag = tag
#        self.current_directory = os.path.dirname(__file__)
#        self.config_generator_script = os.path.join(self.current_directory, "gen_raw_config.sh")
#        self.config_generator_cmd = '{script} {tag}'.format(
#                script=self.config_generator_script,
#                tag=self.tag
#                )
#        self.config_dict = {}

    config_getter_script = os.path.join(os.path.dirname(__file__), "config_get.sh")
    configuration_values = ['PDK_VARIANT', 'CLOCK_PERIOD', 'GLB_RT_ADJUSTMENT', 'FP_CORE_UTIL', 'PL_TARGET_DENSITY',
                'SYNTH_STRATEGY', 'SYNTH_MAX_FANOUT', 'FP_PDN_VPITCH', 'FP_PDN_HPITCH', 'FP_ASPECT_RATIO']

    base_config_values = ['DESIGN_NAME', 'VERILOG_FILES', 'CLOCK_PERIOD', 'CLOCK_PORT']


    @classmethod
    def get_header(cls):
        return ",".join(cls.configuration_values)

#    def gen_possible_combos(self):
#        raw_configuration = subprocess.check_output(self.config_generator_cmd.split())
#        raw_configuration = raw_configuration.decode(sys.getfilesystemencoding())
#        for possible_vector in raw_configuration.splitlines():
#            parameters = possible_vector.split()
#            key = parameters[0]
#            self.config_dict[key] = parameters[1:]
    
    @classmethod
    def get_config(cls, design, tag):
        config_params = " ".join(cls.configuration_values)
        config_relative_path = "config.tcl"
        config_path = os.path.join(os.getcwd(), get_run_path(design=design, tag=tag), config_relative_path)
        cmd = "{script} {path} {params}".format(script=cls.config_getter_script, path=config_path, params=config_params)
        config_coded = subprocess.check_output(cmd.split())
        config = config_coded.decode(sys.getfilesystemencoding()).strip()
        config = config.split("##")
        config = list(filter(None, config))

        return config

    @classmethod
    def gen_base_config_legacy(cls, design, base_config_path):
        config_params = " ".join(cls.base_config_values)
        config_relative_path = "designs/{design}/config.tcl".format(design=design)
        config_path = os.path.join(os.getcwd(), config_relative_path)
        cmd = "{script} {path} {params}".format(script=cls.config_getter_script, path=config_path, params=config_params)
        config_coded = subprocess.check_output(cmd.split())
        config = config_coded.decode(sys.getfilesystemencoding()).strip()
        config = config.split("##")
        config = list(filter(None, config))

        f = open(base_config_path, 'w')
        for i in range(len(config)):
            f.write("set ::env({var}) {val}\n".format(var=cls.base_config_values[i], val=config[i]))

        f.close()

    @classmethod
    def gen_base_config(cls, design, base_config_file):
        config_file = os.path.join(get_design_path(design=design), 'config.tcl')
        copyfile(config_file, base_config_file)

        
