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

import sys
import os
from mako.template import Template
import yaml
import argparse
import pkgutil
from mrtutils.mrtTemplateHelper import *
from mrtutils.device import DeviceSpec as DeviceSpec
from mrtutils.updates import *

th = TemplateHelper()


# Initialize the argument parser
def init_args():
    global parser
    parser = argparse.ArgumentParser("Tool to generate device drivers")
    parser.add_argument('-i', '--input', type=str, help='input file to parse', default="")
    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('-t', '--template', type=str, help='path to create template', default="")
    parser.add_argument('-s', '--slave', action='store_true', help='Generates slave driver', default=False)
    

def buildTemplate(object, templateFile, outputFile, replacePattern = r"@file (.*?\.)(.*?) \*/"):
    exists= False
    cr = CodeReplacer()
    newContents =""
    if os.path.isfile(outputFile):
        exists = True
        curFile = open(outputFile, "r")
        text = curFile.read()
        cr.loadText(text)
        cr.loadText(text,replacePattern)

    template = Template(pkgutil.get_data('mrtutils',templateFile) )
    newContents = "\n".join(template.render(obj = object, t = TemplateHelper()).splitlines())
    newContents = cr.insertBlocks(newContents)
    newContents = cr.insertBlocks(newContents,replacePattern)
    cr.printDrops()
    text_file = open( outputFile , "w")
    text_file.write(newContents)
    text_file.close()


def buildTemplate(object, templateFile, outputFile, replacePattern = r"@file (.*?\.)(.*?) \*/"):
    exists= False
    cr = CodeReplacer()
    newContents =""
    if os.path.isfile(outputFile):
        exists = True
        curFile = open(outputFile, "r")
        text = curFile.read()
        cr.loadText(text)
        cr.loadText(text,replacePattern)

    template = Template(pkgutil.get_data('mrtutils',templateFile) )
    newContents = "\n".join(template.render(obj = object, t = TemplateHelper()).splitlines())
    newContents = cr.insertBlocks(newContents)
    newContents = cr.insertBlocks(newContents,replacePattern)
    cr.printDrops()
    text_file = open( outputFile , "w")
    text_file.write(newContents)
    text_file.close()

def buildDeviceSource(device , outputPath, baseName ='', slave = False):

    if baseName == '':
        baseName = device.name.lower() 
    
    device.slave = slave

    if slave:
        #Slave source uses reverse-replacement on templates
        #this means instead of only preserving user-code blocks, we only update gen-code blocks
        th.buildTemplate(device, 'templates/device/device_slave_header.h', outputPath +"/"+baseName + "_slave.h" ,True)
        th.buildTemplate(device, 'templates/device/device_slave_source.c', outputPath +"/"+baseName + "_slave.c", True )
        th.buildTemplate(device, 'templates/device/device_regs_header.h', outputPath +"/"+baseName + "_regs.h" )
    else:
        th.buildTemplate(device, 'templates/device/device_header_template.h', outputPath +"/"+baseName + ".h" )
        th.buildTemplate(device, 'templates/device/device_source_template.c', outputPath +"/"+baseName + ".c" )
        th.buildTemplate(device, 'templates/device/device_regs_header.h', outputPath +"/"+baseName + "_regs.h" )


def main():
    global path
    global parser
    global args

    updateCheck()

    init_args()
    args= parser.parse_args()
    argCount = len(sys.argv)
    
    slave = args.slave
    inputFile = args.input
    path = args.output
    docPath = args.document
    templatePath = args.template

    device = DeviceSpec('unnamed')

    if not templatePath =="":
        templatePath.replace("yml","") 
        contents = pkgutil.get_data('mrtutils','templates/device/device_descriptor_template.yml')
        text_file = open( templatePath + '.yml' , "w")
        text_file.write(contents.decode("utf-8"))
        text_file.close()
        sys.exit()


    if inputFile == "":
        print("No input file specified, use -t to create a template file")
        sys.exit()


    # if os.path.isfile(inputFile):
    print("parsing " + inputFile )
    device.parseYAML(inputFile)


    print(" Generating Register files for " + device.name)
    buildDeviceSource(device, path, slave = slave)

    if not docPath == "":
        #buildTemplate(device, 'templates/device/device_doc.md', docPath +"/README.md" )
        buildTemplate(device, 'templates/device/device_doc.rst', docPath +"/README.rst", replacePattern=r"\*user-block-(.*?)-start(.*?)\*user-block-\1-end\*" )
        buildTemplate(device, 'templates/device/device_regmap.html', docPath +"/REGMAP.html" )
        


if __name__ == "__main__":
    main()