
import os
from panpbtool.conf import globalsetting
from panpbtool.conf import protolabel
from panpbtool.utils import compileproto
from panpbtool.utils import utils
from functools import cmp_to_key

indent = "      "
class lua_protocal:
    name = ''
    module_name = ''
    gname = ''
    desc = ''
    prefix = ''
    protocal_id = 0
    fields = None
    def __str__(self):
        return self.prefix, self.name

def do_export(context):
    project = context.project
    write_path = context.write_path
    if not os.path.exists(write_path):
        os.mkdir(write_path)

    write_dir = write_path + "/" + globalsetting.LUA_OUTPUT_FOLDER
    
    file_lua_path = write_dir + "/" + globalsetting.LUA_OUTPUT_FILENAME
    file_lua = open(file_lua_path,'w')

    file_lua.write('-- Generated By Protocal Editor Do not Edit !!!!!!!!!!!!\n')
    file_lua.write('Protocols = {\n')
    file_lua.write('  Request = {},\n')
    file_lua.write('  Response = {},\n')
    file_lua.write('  Notification = {},\n')
    file_lua.write('}\n')
    
    protocols_dict = {}
    for module in project.modules:
        protocols = module.protocols
        for protocol in protocols:
            prefix = "Protocols"
            if protocol.category == "Request":
                prefix = "Protocols.Request"
            elif protocol.category == "Response":
                prefix = "Protocols.Response"
            elif protocol.category == "Notification":
                prefix = "Protocols.Notification"

            gname = protocol.name
            if gname in protocols_dict.keys():
                oProto = protocols_dict.pop(gname)
                oProto_gname = oProto.gname + '_' + oProto.module_name
                oProto.gname = oProto_gname
                protocols_dict[oProto_gname] = oProto
                gname = gname + '_' + module.name

            proto = lua_protocal()
            proto.id = protocol.id
            proto.name = protocol.name
            proto.gname = gname
            proto.module_name = module.name
            proto.desc = project.get_comment(protocol.location)
            proto.fields = protocol.fields
            proto.prefix = prefix
            protocols_dict[gname] = proto

    sortedItems = sorted(protocols_dict.items(), key = cmp_to_key(lambda x,y: x[1].id-y[1].id))
    for gname, proto in sortedItems:
        file_lua.write('%s.%s = %d;\n'%(proto.prefix,proto.gname,proto.id))
    file_lua.write("\n")

    file_lua.write('ProtocolConfigs = {\n')

    file_lua.write('    modules = {\n')
    for module in project.modules:
        pb_data,pb_len = utils.load_binery_file_base64(write_dir + "/" + module.name + '.pb')
        file_lua.write('        ["%s"] = { namespace = "%s", data = "%s", len = %d },\n'%(module.name, module.namespace, pb_data, pb_len))
    file_lua.write('    },\n')   
    
    file_lua.write('    protocols = {\n')
    for module in project.modules:
        protocols = module.protocols
        protocols = sorted(protocols, key = cmp_to_key(lambda x,y: x.id-y.id))
        requestProtos = filter(lambda x: x.category == "Request", protocols)
        responseProtos = filter(lambda x: x.category == "Response", protocols)
        notificationProtos = filter(lambda x: x.category == "Notification", protocols)
        file_lua.write('        requests = {\n')
        for protocol in requestProtos:
            pb_name = protocol.name
            pb_fullname = protocol.fullname
            module_name = module.name
            file_lua.write('            [%d] = { id = %d, module = "%s", name = "%s", fullname = "%s", ref = %s,},\n'%( \
                        int(protocol.id),int(protocol.id),module_name,pb_name,pb_fullname,'nil'))
        file_lua.write('        },\n')   
        file_lua.write('        responses = {\n')
        for protocol in responseProtos:
            pb_name = protocol.name
            pb_fullname = protocol.fullname
            module_name = module.name
            file_lua.write('            [%d] = { id = %d, module = "%s", name = "%s", fullname = "%s", ref = %s},\n'%( \
                        int(protocol.id),int(protocol.id),module_name,pb_name,pb_fullname,'nil'))
        file_lua.write('        },\n')   
        file_lua.write('        notifications = {\n')
        for protocol in notificationProtos:
            pb_name = protocol.name
            pb_fullname = protocol.fullname
            module_name = module.name
            file_lua.write('            [%d] = { id = %d, module = "%s", name = "%s", fullname = "%s", ref = %s},\n'%( \
                        int(protocol.id),int(protocol.id),module_name,pb_name,pb_fullname,'nil'))
        file_lua.write('        },\n')   

    file_lua.write('    },\n')   
    
    file_lua.write('}\n')   
    file_lua.write('\n')  

    for gname, proto in sortedItems:
        file_lua.write('-- @desc  ')
        file_lua.write(proto.desc)
        file_lua.write('\n')
        fields = proto.fields
        for field in fields:
            file_lua.write('-- @field %-60s %-20s %-10s @'%(field.proto_type.name, field.name, protolabel.get_name(field.label)))
            file_lua.write(project.get_comment(field.location))
            file_lua.write('\n')
        file_lua.write('function %s.as%s(msg)\n'%(proto.prefix, proto.gname))
        file_lua.write('    return msg or { __id = %s.%s }\n'%(proto.prefix, proto.gname))
        file_lua.write('end\n\n')