#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import shutil 
import argparse
import struct
import binascii

def intToBytes(value, length):
    result = []
    for i in range(0, length):
        result.append(value >> (i * 8) & 0xff)
    result.reverse()
    return result

#查看文件后的16进制数据
def ReadBinFile(in_file, type="sum32", en='little', block_size=1024):
    filename, file_type = os.path.splitext(in_file)  
    out_name = None
    checknum_bytes = None

    # 方式一：累加和
    if type == "sum32":
        out_name0 = filename+file_type+".sum32"
        f = open(in_file, "rb")
        o = open(out_name0, "wb+")
        if f and o:      #二进制打开文件
            checknum_all = 0
            if block_size:  
                while True:
                    # 读一块
                    datas = f.read(block_size)
                    if len(datas) == 0:
                        break
                    # 这一块的checknum
                    checknum = 0
                    for j in range(len(datas)):
                        checknum += datas[j]
                        checknum_all += datas[j]  # 总文件的checknum
                    checknum_bytes = checknum.to_bytes(4, en)    #"little", "big"  # 大端序
                    # 写入数据和checknum
                    o.seek(0,2)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
                    o.write(datas) 
                    o.write(bytes(checknum_bytes))  

            else:
                while True:    
                    datas = f.read(1)
                    if len(datas) == 0:
                        break                    
                    checknum_all += datas[0]    # 总文件的checknum
                    o.seek(0,2)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
                    o.write(datas) 

            f.close()
            o.close()

            checknum_all_bytes = checknum_all.to_bytes(4, en)    #"little", "big"  # 大端序
            checknum_all_str = checknum_all_bytes.hex()
            print(in_file, os.path.getsize(in_file), "checknum", checknum_all_str)
            # 输出文件名
            out_name1 = filename+file_type+".sum32["+checknum_all_str+"]"
            shutil.move(out_name0, out_name1)
            # 追加到文件最后
            with open(out_name1, "rb+") as f:
                f.seek(0,2)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
                f.write(bytes(checknum_all_bytes)) 
                f.close()

    elif type == "crc32":
    # 方式2：crc32
        out_name0 = filename+file_type+".crc32"
        f = open(in_file, "rb")
        o = open(out_name0, "wb+")
        if f and o:      #二进制打开文件
            checknum_all = 0
            if block_size:  
                while True:
                    # 读一块
                    datas = f.read(block_size)
                    if len(datas) == 0:
                        break
                    # 这一块的checknum
                    checknum = binascii.crc32(datas)
                    checknum_bytes = checknum.to_bytes(4, en)    #"little", "big"  # 大端序
                    # 写入数据和checknum
                    o.seek(0,2)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
                    o.write(datas) 
                    o.write(bytes(checknum_bytes))  
            else:
                datas = f.read()
                o.seek(0,2)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
                o.write(datas) 

            f.seek(0,0)
            datas = f.read()            
            checknum_all = binascii.crc32(datas)
            f.close()
            o.close()

            checknum_all_bytes = checknum_all.to_bytes(4, en)    #"little", "big"  # 大端序
            checknum_all_str = checknum_all_bytes.hex()
            print(in_file, os.path.getsize(in_file), "checknum", checknum_all_str)
            # 输出文件名
            out_name1 = filename+file_type+".crc32["+checknum_all_str+"]"
            shutil.move(out_name0, out_name1)
            # 追加到文件最后
            with open(out_name1, "rb+") as f:
                f.seek(0,2)  #位移到最后    SEEK_END(值为2)     SEEK_CUR(值为1)  SEEK_SET(值为0)
                f.write(bytes(checknum_all_bytes)) 
                f.close()



if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("n", help="bin文件名，譬如 COAB21232D.bin")
    parser.add_argument("-t", help="校验方式：sum32,crc32, 默认sum32")
    parser.add_argument("-e", help="校验码大小端：little,big, 默认little")
    parser.add_argument("-s", help="分块大小：0,1024,2048, 默认0不分块")

    args = parser.parse_args()
    project = str(args.n)
    type = "sum32"      #默认 累加和
    en = "little"       #默认 checknum 小端
    block_size = 0      #默认 0
    if args.t:
        type = str(args.t)
    if args.e:
        en = str(args.e)
    if args.s:
        block_size = int(args.s)    
    # print(project, type, en)
    ReadBinFile(project, type, en, block_size)

