from fs.copy import copy_fs
from jinja2 import Environment, FileSystemLoader
import json
import os
import re

'''
流程:
一、将resources里面所有文件夹拷贝到当前目录下
二、解析json配置文件,遍历每一项生成/model/view/controller
三、自动运行项目
'''

# 将字符串首字母转换成大写字母
def convertFirstLetterUpper(text_str):
    # return text_str.capitalize()
    # print("////////////////////>>>>", text_str)
    return re.sub("([a-zA-Z])", lambda x: x.groups()[0].upper(), text_str, 1)

# ROOT = os.path.abspath(os.getcwd())
jinja_env = Environment(loader=FileSystemLoader(os.path.join(os.getcwd(), 'templates')))
jinja_env.filters['letterUpper'] = convertFirstLetterUpper
input_dir = None
output_dir = None

def copyFiles(src_dir, dst_dir):
    copy_fs(src_dir, dst_dir)

def handleResources(config):
    # 处理路由页面
    # 遍历config文件,收集所有的action和name,action和name的首字母必须大写
    # 然后才生成路由配置页面
    target_file = os.sep.join(["views", "__init__.py"])
    handleRender(config, 'router.tpl', target_file)

def handleSignal(config):
    # 生成信号槽模块
    target_file = os.sep.join(["application", "signal_manager.py"])
    handleRender(config, 'signal_manager.tpl', target_file)

    target_file = os.sep.join(["controllers", "__init__.py"])
    handleRender(config, 'signal_manager_init.tpl', target_file)

def handleModel(config, application):
    # 将所有有默认值的字段分为一组,没有默认值的字段分为另一组
    # 生成模板代码时,无默认值的字段在前,有默认值的字段字在后
    # 收集表字段信息
    fields = []
    extend = False
    for m in config.get("model").get("fields"):
        fields.append(m.get("name"))
        extend = True
        print(m)

    target_file = os.sep.join(["models", "{}.py".format(config.get("name"))])
    handleRender(config, 'model.tpl', target_file, fields=fields, extend=extend, application=application)

def handleView(config):
    target_file = os.sep.join(["views", "{}.py".format(config.get("name"))])
    handleRender(config, 'view.tpl', target_file)

def handleController(config):
    # 根据模型字段自动从models列表中取出file name信息和class name信息
    target_file = os.sep.join(["controllers", "{}.py".format(config.get("name"))])
    handleRender(config, 'controller.tpl', target_file)

def handleRender(result, tpl, target_file, **kwargs):
    global output_dir
    # print("=========>", result.get("name"), "{}.py".format(result.get("name")))
    jinja_tpl = jinja_env.get_template(tpl)
    content = jinja_tpl.render({ "config": result, **kwargs })
    # print("############", output_dir)
    target_file = os.sep.join([output_dir, target_file])
    if not os.path.exists(os.path.dirname(target_file)):
        os.makedirs(os.path.dirname(target_file))
    
    with open(target_file, 'w', encoding='utf-8') as f:
        f.write(content)

def parseConfig(config):
    # 解析配置文件
    for cfg in config.get("apis"):
        handleModel(cfg, config.get("application"))
        handleView(cfg)
        handleController(cfg)
    handleResources(config.get("apis"))
    handleSignal(config.get("apis"))

def readConfig():
    result = {}
    with open("config.json", "r+") as f:
        result = json.loads(f.read())
    return result

def run():
    global input_dir
    global output_dir
    input_dir = os.sep.join([os.getcwd(), "resources"])
    output_dir = os.sep.join([os.getcwd(), "build_out"])
    copyFiles(input_dir, output_dir)
    config = readConfig()
    # print(config)
    parseConfig(config)
    print("success ......")

if __name__ == "__main__":
    run()