import sys
import os
import datetime
from datetime import datetime, timedelta
import mycopy



# 定义软件版本号
SOFT_VERION = "2.10"



# 定义mod文件的名称和路径
MOD_FILE="mod_signals.c"
MOD_PATH="./source/task/"
INFO_FILE="./source/main/compiler_info.h"
BOOTCODE_ARRAY="./source/main/bootcode.txt"


# 找到文件夹中指定后缀的文件
def find_file(path:str,fix:str):
    file_list=[]
    for file_name in os.listdir(path):
        if file_name.endswith(fix):
            file_list.append(os.path.join(path, file_name))
    return file_list

# 找到 signal 关键字 定义的行
def find_signal_def(file):
    list_signal=[]
    with open(file,encoding="utf-8") as f:
        list_str=f.readlines()
        for i in list_str:
            if(i[0:6]=="signal"):
                list_signal.append(i)
    return list_signal

# 截取参数列表中的变量名
def split_par_name(par_str:str):
    ret_str=""
    if(par_str.count('*')>0):
        ret_str=par_str.split("*")[1].strip()
    else:
        ret_str=par_str.split(" ")[1]
    return ret_str

# 生成一个信号函数的实现
def def_signal_fun(line:str):
    # 删除多余空格
    line=' '.join(line.split())
    # print(line)
    list_str=line.split('(')
    fun_name=list_str[0].split(' ')[1]
    param_str=list_str[1].split(')')[0]
    params=[]
    # 有","则至少有两个参数否则可能有一个参数,可能没有
    if(param_str.count(',')>0):
        params=param_str.split(',')
        for i in range(len(params)):
            params[i]=params[i].strip()
    else:
        t_str=param_str.strip()
        if(len(t_str)>0)and(t_str!="void"):
            params.append(t_str)
    # print(fun_name,params)
    params_num=len(params)
    fun_str=""
    fun_str+="void "+fun_name+"("
    for i in range(params_num):
        fun_str+=params[i]
        if(i<len(params)-1):
            fun_str+=","
    fun_str+=")\n{\n"
    if(params_num-1>0):
        fun_str+="  uint32_t param[{d}];\n".format(d=params_num-1)
    for i in range(params_num-1):
        fun_str+="  param[{d1}]=(uint32_t){d2};\n".format(d1=i,d2=split_par_name(params[i+1]))
    if(params_num-1>0):
        fun_str+="  _signal_emit({d1},{d2},param,{d3});\n".format(d1=split_par_name(params[0]),d2=fun_name,d3=params_num-1)
    else:
        fun_str+="  _signal_emit({d1},{d2},0,{d3});\n".format(d1=split_par_name(params[0]),d2=fun_name,d3=params_num-1)
    fun_str+="}\n"
    fun_str+="signal_export({d});\r\n\r\n\r\n\r\n".format(d=fun_name)
    # print(fun_str)
    return fun_str

# 遍历路径中的 .h 文件 返回找到的文件和信号声明
def ergodic_signal_fun(path):
    fun_str=""
    list_file=find_file(path,".h")
    for i in list_file:
        list_signal=find_signal_def(i)
        for j in list_signal:
            fun_str+=def_signal_fun(j)
    return list_file,fun_str

# 创建 mod 文件
def mod_file_creat(file_path):
    with open(file_path,"w+") as f:
        list_file,fun_str=ergodic_signal_fun(MOD_PATH)
        f.write("#include \"stdlib.h\"\n")
        f.write("#include \"signal.h\"\n")
        for i in list_file:
            f.write("#include \""+i.split("/")[-1]+"\"\n")
        f.write("\n\n\n\n\n\n")
        f.write(fun_str)





# 获取北京时间
def get_date():
    now_time = datetime.utcnow()
    utc_time = now_time + timedelta(hours=8)  # UTC只是比北京时间提前了8个小时
    utc_time = utc_time.strftime("%Y%m%d")
    return utc_time

# 获取北京时间
def get_time():
    now_time = datetime.utcnow()
    utc_time = now_time + timedelta(hours=8)  # UTC只是比北京时间提前了8个小时
    utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S")
    return utc_time


# 生成编译信息头文件
def creat_compile_info(dst:str):
    utc_time=get_time()
    if os.path.exists(dst):
        os.remove(dst)
    with open(dst,"w") as f:
        f.write("#ifndef compiler_info__\n")
        f.write("#define compiler_info__\n\n\n\n\n\n\n")
        f.write("#define BUILD_DATE  \""+utc_time+"\"\n")
        f.write("#define SOFT_VERSION  \""+SOFT_VERION+"\"\n")
        f.write("\n\n\n\n\n\n\n#endif\n")


# 生成bootcode数组
def creat_bootcode(dst:str):
    if os.path.exists(dst):
        os.remove(dst)
    data=bytearray()
    boot_file=mycopy.BOOT_FILE_SRC+".bin"
    if(os.path.exists(boot_file)):
        with open(boot_file,"rb") as f:
            data=f.read()
    with open(dst,"w") as f:
        while len(data)>0:
            if(len(data)>=20):
                t=data[0:20]
                data=data[20:]
            else:
                t=data
                data=[]
            s=t.hex(" ")
            s="0x"+s.replace(" ",",0x")+",\n"
            f.write(s)



def main():
    creat_bootcode(BOOTCODE_ARRAY)
    creat_compile_info(INFO_FILE)
    mod_file_creat(MOD_PATH+MOD_FILE)
    print("prepare success.\n")



if __name__=="__main__":
    main()



