import re
import os





elf_name = "antaris_exo_core"
#elf_name = "test_mod"



srec_p = "srec_cat"


#flash_build_address = 0x04000000
flash_build_address = 0x08010000

flash_build_address_str = hex(flash_build_address)
binary_start_addr = hex(flash_build_address + 0x30)

cmd = str("arm-none-eabi-size --format=GNU --totals  {}.elf > size_info.txt".format(elf_name))
returned_value = os.system(cmd)

cmd = str("arm-none-eabi-objcopy --only-section=.hdrinfo -v -O binary {}.elf  header_only.bin".format(elf_name))
returned_value = os.system(cmd)

cmd = str("arm-none-eabi-objcopy  -O ihex  --only-section=.hdrinfo {}.elf  header_only.hex".format(elf_name))
returned_value = os.system(cmd)

cmd = str("arm-none-eabi-objcopy  -O ihex  --remove-section=.hdrinfo {}.elf  binary_only.hex".format(elf_name))
returned_value = os.system(cmd)

#cmd = "C:\srecord\srec_cat.exe binary_packer_only_header_CRC.hex -Intel -o binary_packer_only_header_CRC_Hex2Bin.bin -Binary"
#returned_value = os.system(cmd)


#cmd = str("arm-none-eabi-size --format=GNU --totals  {}.elf > size_info_{}.txt".format(elf_name,elf_name))
#returned_value = os.system(cmd)



#      text       data        bss      total filename
#       844        176         36       1056 binary_packer.elf
#       844        176         36       1056 (TOTALS)

# bss section consumes huge bin size so code size 12920 and data size 616 is assumed as length

data_parsing = []
data_parse = []
count = 0
code_size = 0
code_size_hex = 0xffffffff
size_byte = 0xff
code_size_in_4byte = [1,2,3,4]
code_size_input = "12345678"
data_size_input = "12345678"
bss_size_input = "12345678"
ram_size_input = "12345678"
temp_buffer = ['1','2','3','4','5','6','7','8']
ram_size_in_4byte = [1,2,3,4]



with open('size_info.txt','r') as f_size:
    read_lines = f_size.readlines()
    match = re.search(r'(.*)\(TOTALS\)',read_lines[2])
    if match:
        #data_parsing = match.group(1)
        data_parsing = match.group(0)
        data_parsing = re.split("\s+", data_parsing)
        #print(data_parsing)
        #print(data_parsing[1])
        for x in data_parsing:
            #print(x)
            data_parse = x
            count = count +1
        #print(data_parse)
        #print(count)
        if data_parsing[count-1] == "(TOTALS)" :
            #print("total found")
            print("extracted raw data: ")
            #code_size = int(data_parsing[count-5])
            code_size_input = data_parsing[count-5]
            data_size_input = data_parsing[count-4]
            bss_size_input = data_parsing[count-3]
            binary_size_input = data_parsing[count-2]
            #code_size_hex = hex(code_size)
            print("code size",code_size_input)
            print("data size",data_size_input)
            print("bss size",bss_size_input)
            print("full binary size",binary_size_input)
            ram_size_input = str(int(data_size_input) + int(bss_size_input))
            code_data_size_input = str(int(data_size_input) + int(code_size_input) + 20 + flash_build_address)
            print("calculated code + data ",code_data_size_input)
            print("calculated ram ",ram_size_input)
            #code_size_str = str(code_size_hex)
            binary_size_input = code_data_size_input
            code_data_size_input = str(int(data_size_input) + int(code_size_input) + 20)
            print("calculated code + data ",code_data_size_input)

    else :
        print("size not found")

f_size.close()


try:
    with open("header_only.bin", "rb") as f:
        with open("header_with_size_info.bin", "wb") as fw:



         #   for i in range(0x1000000):
          #      byte = b'\xff'
         #       fw.write(byte)

            
            for i in range(12):
                byte = f.read(1)
                fw.write(byte) 

            #print("field pos reached to write code and data size")

            # write code size section starts here
            print("\nAppend binary size --------------------\r")
            length = len(code_data_size_input)
            print("binary string length is ",length)


            # fill zero to allign 8 digit 
            len_fill = 8-length
            len_inc =0
            while (len_inc < len_fill):
                temp_buffer[len_inc] = '0'
                len_inc = len_inc+1


            # copy size
            len_inc =0
            while (len_inc < length):
                temp_buffer[len_fill+len_inc] = code_data_size_input[len_inc]
                len_inc = len_inc+1
                

            len_fill = 8-length                
            print("4 byte alligned : ",temp_buffer)

            # convert string into byte            
            len_inc = 0
            buffer_inc =0
            #print(code_size_input)
            while (len_inc < 8):
                code_size_in_4byte[buffer_inc] = int(temp_buffer[0+len_inc]+temp_buffer[1+len_inc])
                len_inc = len_inc+2
                buffer_inc = buffer_inc +1
                
            #write code size on binary
            print("code size in 4 BYTE >> ",code_size_in_4byte)              
            binary_format  = bytearray(code_size_in_4byte)
            fw.write(binary_format)
            #for i in code_size_in_4byte:
            print("hex >> ",hex(code_size_in_4byte[3]),hex(code_size_in_4byte[2]),hex(code_size_in_4byte[1]),hex(code_size_in_4byte[0]))              


            # write ram size section starts here  #################
            print("\nAppend Ram size -----------------------\r")
            length = len(ram_size_input)
            print("ram string length is ",length)


            # fill zero to allign 8 digit 
            len_fill = 8-length
            len_inc =0
            while (len_inc < len_fill):
                temp_buffer[len_inc] = '0'
                len_inc = len_inc+1


            # copy size
            len_inc =0
            while (len_inc < length):
                temp_buffer[len_fill+len_inc] = ram_size_input[len_inc]
                len_inc = len_inc+1
                

            len_fill = 8-length                
            print("4 byte alligned : ",temp_buffer)

            # convert string into byte            
            len_inc = 0
            buffer_inc =0
            #print(code_size_input)
            while (len_inc < 8):
                ram_size_in_4byte[buffer_inc] = int(temp_buffer[0+len_inc]+temp_buffer[1+len_inc])
                len_inc = len_inc+2
                buffer_inc = buffer_inc +1
                
            #write code size on binary
            print("code size in 4 BYTE >> ",ram_size_in_4byte)              
            binary_format  = bytearray(ram_size_in_4byte)
            fw.write(binary_format)
            print("hex >> ",hex(ram_size_in_4byte[3]),hex(ram_size_in_4byte[2]),hex(ram_size_in_4byte[1]),hex(ram_size_in_4byte[0]))              


            
            #write data size on binary
            #fw.write(b'\x34')
            #fw.write(b'\x56')
            #fw.write(b'\x78')
            #fw.write(b'\x90')

            # skip 8 bytes since it was filled above with datta and code size information 
            for i in range(8):
                byte = f.read(1)

            # copy remaining binary
            while byte:
                byte = f.read(1)
                fw.write(byte)                    

            fw.close()
            f.close()
            print("\n !!! Code and Ram Size Updated in header info !!! \r")



            
except IOError:
     print('Error While Opening the file!')



#cmd = "C:\srecord\srec_cat.exe header_with_size_info.bin -binary -output header_with_size_info.hex -Intel"
cmd = str(r"{} header_with_size_info.bin -binary -output header_with_size_info.hex -Intel".format(srec_p))

returned_value = os.system(cmd)


#cmd = "C:\srecord\srec_cat.exe header_with_size_info.hex -Intel -fill 0xFF 0x00000000 0x0000002C -STM32 0x0000002C -o header_with_size_info_CRC.hex -Intel"
cmd = str(r"{} header_with_size_info.hex -Intel -fill 0xFF 0x00000000 0x0000002C -STM32 0x0000002C -o header_with_size_info_CRC.hex -Intel".format(srec_p))
returned_value = os.system(cmd)

cmd_str = str(r"{} binary_only.hex -Intel -fill 0xFF {} {} -STM32 {} -o binary_only_CRC.hex -Intel".format(srec_p,binary_start_addr,binary_size_input,binary_size_input))
#cmd = "C:\srecord\srec_cat.exe binary_only.hex -Intel -fill 0xFF 0x00000030 0x0000041C -STM32 0x41C -o binary_only_CRC.hex -Intel"
returned_value = os.system(cmd_str)

offset_addr = str(int(binary_size_input)+4)
#offset_addr = binary_size_input

print(flash_build_address)
print(offset_addr)

print(hex(int(flash_build_address)))
print(hex(int(offset_addr)))


cmd_crop = str(r"{} binary_only_CRC.hex -Intel -crop  {}  {}  -offset  -{} -o binary_only_CRC_offset.hex -Intel".format(srec_p,flash_build_address,offset_addr,flash_build_address))
returned_value = os.system(cmd_crop)


cmd = str(r"{} header_with_size_info_CRC.hex -Intel binary_only_CRC_offset.hex -Intel -o {}_final.hex -Intel".format(srec_p,elf_name))
returned_value = os.system(cmd)

cmd = str(r"{} {}_final.hex -Intel -o {}_final.bin -Binary".format(srec_p,elf_name,elf_name))
returned_value = os.system(cmd)

print("Header CRC append at 0x0000002C")

print("Binary CRC append at ",hex(int(binary_size_input)))

