#!/usr/bin/python3
#
#@file make_protocol.py
#@brief python script to generate code for PolyPacket
#@author Jason Berger
#@date 02/19/2019
#

import sys
import xml.etree.ElementTree as ET
import re
import io
import os
import copy
import datetime
import zlib
import argparse
#import pdfkit
from shutil import copyfile
from mako.template import Template
import pkgutil
import polypacket
import subprocess
from polypacket.protocol import *

args = None
parser = None

now = datetime.datetime.now()
path ="./"



def buildTemplate(protocol, templateFile, outputFile):
    template = Template(pkgutil.get_data('polypacket',templateFile) )
    text_file = open( outputFile , "w")
    text_file.write("\n".join(template.render(proto = protocol).splitlines()))
    #text_file.write(template.render(proto = protocol))
    text_file.close()

def initRepo(path):
    subprocess.check_output(['git','init',path] )


def addSubModule(gitpath, suburl, subpath):
    path = os.getcwd()
    os.chdir(gitpath)
    subprocess.check_output(['git','submodule','add', suburl,  subpath] )
    os.chdir(path)


def genUtility(protocol, inputFile, path):
    protocol.utilName = os.path.basename(path)
    path+="/"
    srcPath = path +"src/"
    libPath = path +"src/lib/"
    buildPath = path+"build/"
    docPath = path+"doc/"
    polyPath = path+"MrT/Modules/Utilities/PolyPacket"
    xmlPath = os.path.dirname(inputFile)

    if not os.path.isdir(path):
        os.makedirs(path)
        initRepo(path)
        addSubModule(path, "https://github.com/uprev-mrt/libCOBS.git" ,"MrT/Modules/Utilities/COBS")
        addSubModule(path, "https://github.com/uprev-mrt/libPolyPacket.git" ,"MrT/Modules/Utilities/PolyPacket")
        addSubModule(path, "https://github.com/uprev-mrt/libJSON.git" ,"MrT/Modules/Utilities/JSON")
        addSubModule(path, "https://github.com/uprev-mrt/platform-common.git" ,"MrT/Modules/Platforms/Common")
        addSubModule(path, "https://github.com/uprev-mrt/platform-linux.git" ,"MrT/Modules/Platforms/Linux")
        os.makedirs(srcPath)
        os.makedirs(libPath)
        os.makedirs(buildPath)
        os.makedirs(docPath)
    os.system('cp '+ inputFile +' '+ path)
    #os.system('cp '+ script_dir+'/linux_uart/linux_uart* '+ libPath)
    #TODO commit

    protocol.genUtility = True
    buildTemplate(protocol, 'templates/cmake_template.txt', path + 'CMakeLists.txt')
    buildTemplate(protocol, 'templates/c_header_template.h', libPath + protocol.fileName+".h")
    buildTemplate(protocol, 'templates/c_source_template.c', libPath + protocol.fileName+".c")
    buildTemplate(protocol, 'templates/app_template.h', srcPath+"app_" + protocol.name.lower() +".h")
    buildTemplate(protocol, 'templates/app_template.c', srcPath+"app_" + protocol.name.lower()+".c")
    buildTemplate(protocol, 'templates/util_main_template.c', srcPath+"main.c")
    buildTemplate(protocol, 'templates/doc_template.md', docPath + protocol.name+"_ICD.md")
    buildTemplate(protocol, 'templates/doc_template.html', docPath + protocol.name+"_ICD.html")
    protocol.genUtility = False #set this back in case someone does this out of order

# Initialize the argument parser
def init_args():
    global parser
    parser = argparse.ArgumentParser("Tool to generate code and documentation for PolyPacket protocol")
    parser.add_argument('-i', '--input', type=str, help='input file to parse', required=True)
    parser.add_argument('-o', '--output', type=str, help='Output path', default="")
    parser.add_argument('-d', '--document', type=str, help='documentation path', default="")
    parser.add_argument('-j', '--javascript', type=str, help='javascript output path', default="")
    parser.add_argument('-a', '--app', action='store_true', help='Generates the app layer code to fill out', default=False)
    parser.add_argument('-s', '--snippets', action='store_true', help='Adds helpful code snippets to files', default=False)
    parser.add_argument('-u', '--utility', type=str, help='Output path for Linux host utility application', default="")
    parser.add_argument('-m', '--html', action='store_true', help='Generates html doc', default=False)



def main():
    global path
    global parser
    global args

    init_args()
    args= parser.parse_args()
    argCount = len(sys.argv)

    inputFile = args.input
    path = args.output
    utilPath = args.utility
    docPath = args.document
    jsPath = args.javascript

    fileCrc = crc(inputFile)

    print( "Parsing " + inputFile)

    protocol = buildProtocol(inputFile)

    protocol.hash = fileCrc
    print( "Protocol "+ protocol.name+ " generated!")
    protocol.genTime = now.strftime("%m/%d/%y")

    protocol.snippets = args.snippets

    #get path of this script so we can run remotely
    script_dir = os.path.dirname(__file__)
    xmlPath = os.path.dirname(inputFile)


    if(docPath != ""):
        buildTemplate(protocol, 'templates/doc_template.md', docPath +"/"+ protocol.name+"_ICD.md")
        buildTemplate(protocol, 'templates/doc_template.html', docPath +"/"+ protocol.name+"_ICD.html")
        #pdfkit.from_file(xmlPath + protocol.name+"_ICD.html", xmlPath + protocol.name+"_ICD.pdf" )

    if(jsPath != ""):
        buildTemplate(protocol,  'templates/javascript_template.js', jsPath + protocol.fileName+".js");

    if(utilPath != ""):
        print ("Generating Utility from:" +inputFile)
        genUtility(protocol,inputFile, utilPath)

    if(path != ""):
        buildTemplate(protocol, 'templates/c_header_template.h', path+"/" + protocol.fileName+".h")
        buildTemplate(protocol, 'templates/c_source_template.c', path+"/" + protocol.fileName+".c")

        if(args.app):
            buildTemplate(protocol,'templates/app_template.h', path+"/app_" + protocol.name.lower() +".h")
            buildTemplate(protocol, 'templates/app_template.c', path+"/app_" + protocol.name.lower()+".c")




if __name__ == "__main__":
    main()
