import datetime
import shutil


class Generate_link():
    def __init__(self):

        curr_time = datetime.datetime.now()
        self.time_str = curr_time.strftime("%Y-%m-%d")
    def get_info(self, lnk_filename, lnk_filename2, output):
        vector_count = 1
        d_count = 0
        LEA_flag = 0
        RAM_length2 = 0
        memory_type = ''
        device = self.get_device(lnk_filename)
        if device.find("fr") >= 0:
            memory_type = "FRAM"
        flash_data = self.getAddrLenInFile(lnk_filename, memory_type)
        ram_data = self.getAddrLenInFile(lnk_filename, "RAM")
        with open(lnk_filename) as file_object:
            linesl = file_object.readlines()
        for linel in linesl:
            if linel.find("{ * ( .int") >= 0:
                vector_count += 1
            if linel.find("LEARAM") >= 0:
                LEA_flag = 1
        RAM_start_addr = int(ram_data[0], 16)
        if LEA_flag == 0:
            RAM_length = int(ram_data[1], 16) - vector_count * 2
        else:
            RAM_length = int(ram_data[1], 16)
            RAM_length2 = int(ram_data[1], 16) - vector_count * 2
        RAM_END = RAM_start_addr + RAM_length - 1
        RAM_END_IAR = RAM_start_addr + int(ram_data[1], 16) - 1
        flex_type = ''
        dual_start_addr = 0x0
        appl_start_addr = int(flash_data[0], 16)
        # print(flash_data)
        appl_end_addr = int(flash_data[0], 16) + int(flash_data[1], 16) - 1

        RAM_END_IAR_FIND = '-' + str(hex(RAM_END_IAR))
        RAM_END_IAR_FIND = RAM_END_IAR_FIND.replace("-0x", "-")
        RAM_END_IAR_FIND = RAM_END_IAR_FIND.upper()
        # print(RAM_END_IAR_FIND)
        FRAM_END_IAR_FIND = '-' + str(hex(appl_end_addr))
        FRAM_END_IAR_FIND = FRAM_END_IAR_FIND.replace("-0x", "-")
        FRAM_END_IAR_FIND = FRAM_END_IAR_FIND.upper()

        filename_OutBootCCS = output+'/'+device + "_Boot_CCS.cmd"
        filename_OutAppCCS = output+'/'+device + "_App_CCS.cmd"
        filename_bsl_app_h = output+'/'+"bsl_app.h"
        filename_OutBootIAR = output+'/'+device + "_Boot_IAR.xcl"
        filename_OutAppIAR = output+'/'+device + "_App_IAR.xcl"

        shutil.copyfile('Linker_template/template_Boot_CCS_flex.tmpl', filename_OutBootCCS)
        shutil.copyfile('Linker_template/template_bsl_app.tmpl', filename_bsl_app_h)
        # shutil.copyfile(lnk_filename + '.cmd', filename_OutAppCCS)
        shutil.copyfile('Linker_template/template_Boot_IAR_flex.tmpl', filename_OutBootIAR)
        shutil.copyfile(lnk_filename2, filename_OutAppIAR)
        ##### Replace text in Boot CCS file#######################################################################################################
        self.replacetextinFile(filename_OutBootCCS, '<DATE>', self.time_str)
        self.replacetextinFile(filename_OutBootCCS, '<DEVICE>', device)
        self.replacetextinFile(filename_OutBootCCS, '<RAM_START>', str(hex(RAM_start_addr)))
        self.replacetextinFile(filename_OutBootCCS, '<RAM_LEN>', str(hex(RAM_length)))
        ##### Replace text in App CCS file###########################################################################################################
        file_data = ""
        Length_Buf = 0
        with open(lnk_filename, "r") as file_object:
            for linel in file_object:
                if LEA_flag == 0:
                    if linel.find("  RAM         ") >= 0:
                        linell = linel.replace(',', ' ')
                        data_array = linell.split()
                        Length_Buf = int(data_array[7], 16) - vector_count * 2
                        linel = linel.replace("length = " + data_array[7], "length = " + str(hex(Length_Buf)))
                if linel.find("  FRAM         ") >= 0:
                    linell = linel.replace(',', ' ')
                    data_array = linell.split()
                    Length_Buf = int(data_array[7], 16) - vector_count * 2 - 0x42
                    linel = linel.replace("length = " + data_array[7], "length = " + str(hex(Length_Buf)))
                if linel.find("JTAGSIGNATURE") >= 0 or linel.find("BSLSIGNATURE") >= 0:
                    d_count += 1
                else:
                    file_data += linel
        with open(filename_OutAppCCS, "w") as file_object:
            file_object.write(file_data)
        ##### Replace text in Boot IAR file#######################################################################################################
        self.replacetextinFile(filename_OutBootIAR, '<DATE>', self.time_str)
        self.replacetextinFile(filename_OutBootIAR, '<DEVICE>', device)
        self.replacetextinFile(filename_OutBootIAR, '<BOOT_RAM_START>', str(hex(RAM_start_addr)))
        self.replacetextinFile(filename_OutBootIAR, '<BOOT_RAM_END>', str(hex(RAM_END)))
        ##### Replace text in App IAR file#######################################################################################################
        FRAM_END = int(data_array[4], 16) + int(data_array[7], 16) - vector_count * 2 - 0x42
        FRAM_END_BUFF = str(hex(FRAM_END))
        FRAM_END_BUFF = FRAM_END_BUFF.replace("0x", "-")
        FRAM_END_BUFF = FRAM_END_BUFF.upper()
        # print(FRAM_END_BUFF)
        RAM_END_BUFF = str(hex(RAM_END))
        RAM_END_BUFF = RAM_END_BUFF.replace("0x", "-")
        RAM_END_BUFF = RAM_END_BUFF.upper()

        self.replacetextinFile(filename_OutAppIAR, FRAM_END_IAR_FIND, FRAM_END_BUFF)
        self.replacetextinFile(filename_OutAppIAR, RAM_END_IAR_FIND, RAM_END_BUFF)
        ##### Replace text in bsl_app.h file###############################################################
        if LEA_flag == 0:
            RAM_VECTPR_start_add = RAM_start_addr + RAM_length
            RAM_VECTPR_end_add = RAM_start_addr + int(ram_data[1], 16)
        else:
            RAM_VECTPR_start_add = RAM_start_addr + RAM_length2 + 0x1000
            RAM_VECTPR_end_add = RAM_start_addr + int(ram_data[1], 16) + 0x1000
        FRAM_VECTPR_start_add = 0xFF3E - vector_count * 2
        FRAM_VECTPR_start_add_debug = 0x10000 - vector_count * 2

        self.replacetextinFile(filename_bsl_app_h, '<RAM_VECTOR_START>', str(hex(RAM_VECTPR_start_add)))
        self.replacetextinFile(filename_bsl_app_h, '<FRAM_VECTOR_START>', str(hex(FRAM_VECTPR_start_add)))
        self.replacetextinFile(filename_bsl_app_h, '<FRAM_VECTOR_START_DEBUG>', str(hex(FRAM_VECTPR_start_add_debug)))
        self.replacetextinFile(filename_bsl_app_h, '<RAM_VECTOR_END>', str(hex(RAM_VECTPR_end_add)))

    def getAddrLenInFile(self, cmd_f, mem_type):
        return_list = []
        with open(cmd_f) as file_object:
            lines = file_object.readlines()
        for line in lines:
            if line.find("    " + mem_type + "         ") >= 0:
                line = line.replace(',', ' ')
                data_array = line.split()
                return_list.append(data_array[4])
                return_list.append(data_array[7])
                return return_list
        return return_list
    def get_device(self, link_file):
        with open(link_file) as file_object:
            lines = file_object.readlines()
        for line in lines:
            if (line[0] == '-') and (line[1] == 'l'):
                line = line.replace('.', ' ')
                data_array = line.split()
                #			print(data_array)
                return data_array[1]
    def replacetextinFile(self, file, old_str, new_str):
        file_data = ""
        with open(file, "r") as f:
            for line in f:
                if old_str in line:
                    line = line.replace(old_str, new_str)
                file_data += line
        with open(file, "w") as f:
            f.write(file_data)
