#!/usr/bin/python3
import xml.etree.ElementTree as ET
import yaml
import ast
import sys, os, re

def convert_one_file(file):
    # 解析XML文件到树中
    tree = ET.parse(file)
    root = tree.getroot()
    # 将XML数据转换为Python字典
    data = {}
    #处理枚举
    for enum in root.findall('.//enum'):
        list = []
        id = enum.attrib.get('id')
        for value in enum:
            item = {}
            item['nick'] = value.get('nick')
            item['value'] = value.get('value')
            list.append(item)
        data[f'enum_{id}'] = list
    #处理schema下的key， schema不管
    schema_list = root.findall('.//schema')
    for schema in schema_list:
        schema_map = {}
        keys = {}
        for key in schema.findall('.//key'):
            item = {}
            key_name = key.attrib.get('name')
            key_type = key.attrib.get('type')
            #type 不存在 就是枚举类型
            if key_type is None:
                enumid = key.attrib.get('enum')
                item['range'] = f'@enum_{enumid}'
                item['_type'] = 'enum'
                for child in key:
                    tag = child.tag
                    item[tag] = child.text.strip('\'')
            else:
                item['_type'] = key_type
                for child in key:
                    text = ""
                    tag = child.tag
                    text = child.text
                    if text is None:
                        text = ''
                    text = text.strip() #去掉前后空白，否则可能影响ast.literal_eval解析字符串
                    text = text.strip('\'') #部分xml空字符串默认值会写''
                    text = text.strip('\"') #部分xml空字符串默认值会写''
                    text = text.replace('\t','') #删除原xml中使下一行缩进而使用的制表符
                    if tag == 'range':
                        item['range'] = f'{child.attrib.get("min")},{child.attrib.get("max")}'
                    # if tag == 'default':
                    #     if key_type[0] in 'isbdtou': 
                    #         item['default'] = text
                    #     else:
                    #         parser_data = ast.literal_eval(text.strip())
                    #         item['default'] = parser_data
                    else:
                        item[tag] = text
            keys[key_name] = item
        if keys:
            schema_map['keys'] = keys
        data[schema.attrib.get('id').rsplit('.', maxsplit = 1)[1]] = schema_map
    return data

# 转换单个app的所有配置文件，并生成到一个yaml文件中
if __name__ == '__main__': 
    app_name = sys.argv[1]
    version = '2.0.0-0k0.0'
    if 3 == len(sys.argv):
        version = sys.argv[2]
    # 读取app的所有配置文件
    app_config_files = {}
    file_list = []
    for root, dirs, files in os.walk("/usr/share/glib-2.0/schemas"):
        if f'{app_name}.gschema.xml' in files:
            app_config_files[app_name] = convert_one_file(os.path.join(root, f'{app_name}.gschema.xml'))
        for file in files:
            if re.match(app_name + r'\..*' + '.gschema.xml' + r'$', file):
                file_path = os.path.join(root, file)
                app_config_files[file_path[28:-12]] = convert_one_file(file_path)
                file_list.append(file_path[28:-12])
    # 将配置合并
    # 按照每个元素分割后的字符串个数对列表进行降序排序
    file_list = sorted(file_list, key=lambda x: len(x.split('.')), reverse= True)
    # if app_name in file_list:
    #     file_list.remove(app_name)
    parent = ''
    child = ''
    for key in file_list:
        if key == app_name:
            break
        list = key.rsplit('.',maxsplit=1)
        parent = list[0]
        child = list[1]
        # 将本文件的字典 添加到父文件的 'children'组中
        if parent in app_config_files:
            if 'children' not in app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]:
                app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]['children'] = {}
            app_config_files[parent][parent.rsplit('.',maxsplit = 1)[1]]['children'].update(app_config_files[key])
        else:
            tmp_map = {parent.rsplit('.',maxsplit = 1)[1]:{'children':{}}}
            tmp_map[parent.rsplit('.',maxsplit = 1)[1]]['children'].update(app_config_files[key])
            key = parent
            app_config_files[parent] = tmp_map
            file_list.append(parent)
    # 添加假的版本号  生成后需要手改为包的正确版本
    data = {}
    data[app_name.rsplit('.',1)[1]] = {}
    data[app_name.rsplit('.',1)[1]][version] = app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]]

    if 'keys' in app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]].keys():
        data[app_name.rsplit('.',1)[1]][version]['keys'] = app_config_files[app_name][app_name.rsplit('.',maxsplit=1)[1]]['keys']
    
    # 生成yaml文件       
    yaml_data = yaml.safe_dump(data,allow_unicode = True)

    # 将YAML数据写入文件
    file = f"/home/kylin/yaml/{app_name}.yaml"
    if not os.path.exists('/home/kylin/yaml'):
        os.makedirs('/home/kylin/yaml')
    with open(file, 'w') as yaml_file:
        yaml_file.write(yaml_data)
