#!/usr/bin/env python

from pickle import FALSE
import sys
import os
import argparse
from mako.template import Template
from mrtutils.mrtTemplateHelper import *
import git
import re
from mrtutils.updates import *
import subprocess

args = None
parser = None

#def filter_commits:

th = TemplateHelper()


class VersionStruct:
    def __init__(self):
        self.major = 0
        self.minor = 0
        self.patch = 0
        self.build = 0
        self.branch = "none"
        self.prefix =""
        self.hash = ""
        self.useTags = False
        self.fileName =""
        self.repo = None

    def loadFile(self, path):
        f = open(path)
        txt = f.read()
        self.fileName = path
        
        reMajor = re.compile(r'VERSION_MAJOR\s*?(\S*?)\s*?\n' )
        reMinor = re.compile(r'VERSION_MINOR\s*?(\S*?)\s*?\n' )
        rePatch = re.compile(r'VERSION_PATCH\s*?(\S*?)\s*?\n' )
        reBuild = re.compile(r'VERSION_BUILD\s*?(\S*?)\s*?\n' )
        
        mMajor = reMajor.findall(txt)
        mMinor = reMinor.findall(txt)

        mPatch = rePatch.findall(txt)
        mBuild = reBuild.findall(txt)

        self.major = int(mMajor[0][0].strip())
        self.minor = int(mMinor[0][0].strip())
        self.patch = int(mPatch[0][0].strip())
        self.build = int(mBuild[0][0].strip())
        

        ##TODO parse version.h file
    
    def loadRepo(self,repo):

        self.repo = repo

        try: 
            self.branch = repo.active_branch.name
        except:
            self.branch = 'DETACHED_' + repo.head.object.hexsha
            print("Repo in Detached head state")
            
        self.hash = repo.head.commit.hexsha



    def setMajor(self, str):

        if str[0] == '+':
            val = int(str[1:])
            self.major += val 
            self.minor = 0
            self.patch = 0
        
        else:
            self.major = int(str)

    def setMinor(self, str):
        
        if str == 'auto':
            self.patch = self.getCommitsSinceLast('master', change='major')
            self.patch = 0
        elif str[0] == '+':
            val = int(str[1:])
            self.minor += val 
            self.patch = 0
        
        else:
            self.minor = int(str)

    def setPatch(self, str):

        if str == 'auto':
            self.patch = self.getCommitsSinceLast('master', change='minor')
        elif str[0] == '+':
            val = int(str[1:])
            self.patch += val   
        else:
            self.patch = int(str)

    def setBuild(self, str):

        if str[0] == '+':
            val = int(str[1:])
            self.build += val 
        
        else:
            self.build = int(str)

    def getCommitsSinceLast(self, branch = 'master', change= 'minor' ):
    
        repattern = None
        count = 1

        if change == 'minor':
            repattern = re.compile(r'\+.*?VERSION_MINOR\s*?(\S*?)\s*?\n' )
        elif change == 'major':
            repattern = re.compile(r'\+.*?VERSION_MAJOR\s*?(\S*?)\s*?\n' )
        
        commit = self.repo.commit(branch)
        firstParent = None 

        #iterate through using first-parent method 
        while(len(commit.parents) > 0):
            firstParent = commit.parents[0]

            try:
                diff = self.repo.git.diff(firstParent, commit, self.fileName)
            except:
                return 0

            if repattern.search(diff):
                    return count
            
            count+= 1
            commit = firstParent

        
        return 0


    def print(self, format: str):

        out = format
        out = out.replace("$MAJOR", str(self.major))
        out = out.replace("$MINOR", str(self.minor))
        out = out.replace("$PATCH", str(self.patch))
        out = out.replace("$BUILD", str(self.build))
        out = out.replace("$BRANCH", self.branch)
        out = out.replace("$HASH", self.hash)

        print(out)





  

# Initialize the argument parser
def init_args():
    global parser
    parser = argparse.ArgumentParser("Tool to generate version file")
    parser.add_argument('versionFile', type=str, nargs='?', help='version header file', default="version.h")
    parser.add_argument('-m', '--major', type=str, help='Major version', default="")
    parser.add_argument('-n', '--minor', type=str, help='Minor version', default="")
    parser.add_argument('-p', '--patch', type=str, help='Patch', default="")
    parser.add_argument('-b', '--build', type=str, help='build number', default="")
    parser.add_argument('-t', '--tags', action='store_true', help='use version tags in repo', default=False)
    parser.add_argument('-f', '--format', type=str, help='Output format', default="$MAJOR.$MINOR.$PATCH")

    

def main():
    global parser
    global args
    init_args()
    args = parser.parse_args() 
    vs = VersionStruct()
    th = TemplateHelper()
    
    if args.tags :
        vs.useTags = True 


    repo = git.Repo(os.getcwd())
    vs.loadRepo(repo)

    if os.path.isfile(args.versionFile):
        vs.loadFile(args.versionFile)

    if not args.major == "":
        vs.setMajor(args.major)
    if not args.minor == "":
        vs.setMinor(args.minor)
    if not args.patch == "":
        vs.setPatch(args.patch)
    if not args.build == "":
        vs.setBuild(args.build)

    th.buildTemplate(vs, 'templates/version/version.h' , args.versionFile)



    vs.print(args.format)



if __name__ == "__main__":
    main()