#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
import xml.etree.ElementTree as ET

svn_server = "https://svn.netentertainment.com/"
svn_path = "cm_games_ng/igames/"

fakeChangingCalls = True

#####################
# Main program loop #
#####################
def main(argv):

    print("main(%s)" % (argv))

    games = getGamesList(argv)
    components = getComponentsList(argv)

    printHelpText()

    for game in games:
        for component in components:
            componentSvnName = createComponentName(game, component)
            print("\n********** [RELEASE] " + componentSvnName + " **********\n")
            url = "%s%s%s/%s/" % (svn_server, svn_path, game, componentSvnName)

            print(" - Step 1) Check out the trunk")
            dirPath = os.path.join(".", game, componentSvnName, "trunk")
            try:
                os.makedirs(dirPath)
            except FileExistsError:
                pass

            svnCheckoutOrUpdate(url + "trunk", dirPath)

            print(" - Step 2) Branch the trunk")
            try:
                trunkVersion = getTrunkVersion(dirPath).split(".")
                major = trunkVersion[0]
                minor = trunkVersion[1]
                patch = trunkVersion[2]
                newBranchName = "%s-%s.%s.x" % (componentSvnName, major, minor)
                newDevelopmentVersion = "%s.%s.0" % (major, str(int(minor) + 1))

                mavenReleaseBranch(dirPath, newBranchName, newDevelopmentVersion)

                print(" - Step 3) Check out the branch")
                dirPath = os.path.join(".", game, componentSvnName, "branches", newBranchName)
                svnCheckoutOrUpdate(url + "branches/" + newBranchName, dirPath)

                if svnHasChanges("%s%s%s/%s/trunk" % (svn_server, svn_path, game, componentSvnName)) :

                    print(" - Step 4) Update dependencies")
                    mavenUpdateBranchDependencies(dirPath)

                    print(" - Step 5.a) Release(prepare)")
                    mavenReleasePrepareBranch(dirPath)

                    print(" - Step 5.b) Release(perform)")
                    #releasePerformBranch(dirPath)
                    mavenReleasePerformBranch(dirPath)

                    # print(" - Step 6) Verify that everything turned out great (how do we know what tag should be created?)")
                    # newTagName = "%s.%s." % (major, minor)
                    # verifyReleaseSuccess(url + "tags/" + newTagName)
            except IOError as e:
                print("Pom file access failure, aborting release of '%s': %s: '%s'" % (componentSvnName, e.strerror, e.filename))

####################
# Helper functions #
####################
def getGamesList(argv):

    for param in argv:
        if param.startswith("games") :
            listStr = param.split("=")[1]
            print("Game list supplied, will use '" + listStr + "'")
            list = listStr.split(",")
            return list

    list = svnList("%s%s" % (svn_server, svn_path))
    print("No game list supplied, will use listing from svn: " + ','.join(list))
    return list

def getComponentsList(argumentVector):
    for param in argumentVector:
        if param.startswith("components") :
            listStr = param.split("=")[1]
            print("Components list supplied, will use '" + listStr + "'")
            list = listStr.split(",")
            return list

    list = "common,vanilla,openbet"
    print("No game list supplied, will use all known components: " + list)
    list = list.split(",")
    return list

def getTrunkVersion(url) :
    tree = ET.parse(os.path.join(url, "pom.xml"))
    root = tree.getroot()

    version = root.find("{http://maven.apache.org/POM/4.0.0}version")

    print("getTrunkVersion(%s) : %s" % (url, version.text))
    return version.text

def createComponentName(game, component):
    if component == "vanilla" :
        return game
    else :
        return game + "-" + component

def printHelpText() :
    print("--------------------------")
    print("Supported parameters:")
    print("games=<comma separated list of games>")
    print("\tDetails: Just a list of game directory names")
    print("\tRequired: no")
    print("\tDefault: all catalogues in %s%s treated as game names" % (svn_server, svn_path))
    print("\tPossible: all catalogues in %s%s" % (svn_server, svn_path))
    print("components=<comma separated list of sub-components>")
    print("\tDetails: if you state 'components=vanilla,common' the vanilla version will be released BEFORE the common version and this is usually not what you want, so beware that order is relevant")
    print("\tRequired: no")
    print("\tDefault: \"common,vanilla,openbet\"")
    print("\tPossible: Ant/all/none of \"common,vanilla,openbet\"")
    print("--------------------------")

########################
# Subversion functions #
########################
def svnList(url):
    print("svnList(%s)" % url)
    f = os.popen("svn list %s" % url)
    list = f.read().split("\n")
    for i in range(0, len(list)):
        list[i] = list[i].strip("/\\")

    list.remove("");

    return list

def svnHasChanges(url):
    THE_LINE_THAT_THE_RELEASE_MESSAGE_SHOULD_BE_ON = 4

    changeList = os.popen("svn log %s" % url)
    changeCount = 0
    for change in changeList:
        changeCount += 1
        if changeCount > THE_LINE_THAT_THE_RELEASE_MESSAGE_SHOULD_BE_ON :
            print("hasSvnChanges(%s) : %s" % (url, False))
            return False
        if str(change).startswith("[maven-release-plugin] prepare release"):
            print("hasSvnChanges(%s) : %s" % (url, True))
            return True
    print("hasSvnChanges(%s) : %s" % (url, False))
    return False

def svnCheckoutOrUpdate(url, path):
    testFile = os.path.join(path, "pom.xml")
    if os.path.isfile(testFile) :
        f = os.popen("svn up %s" % path)
    else :
        f = os.popen("svn co %s %s" % (url ,path))
    co = f.read()
    print (co)

def svnCommit(path, message):
    if fakeChangingCalls :
        f = os.popen("echo svn commit %s -m \"%s\"" % (path, message))
    else :
        f = os.popen("svn commit %s -m \"%s\"" % (path, message))
    co = f.read()
    print (co)

###################
# Maven functions #
###################
def mavenUpdateBranchDependencies(path) :
    print("updateBranchDependencies(%s)" % path)

    appExecDir = os.path.abspath(os.curdir)
    try:
        os.chdir(path)
        if fakeChangingCalls:
            f = os.popen("echo mvn versions:use-latest-versions")
        else:
            f = os.popen("mvn versions:use-latest-versions")
        co = f.read()
        print(co)

        os.chdir(appExecDir)

        svnCommit(path, "[release script] Updated pom.xml with latest released versions in preparation to run the release command on " + path)
    except FileNotFoundError as e:
        print("[WARNING] Can't open directory %s, skipping branch dependency update. Chances are the branch creation or the checkout of it failed." % path)

def mavenReleasePrepareBranch(path) :
    print("releasePrepareBranch(%s)" % path)

    appExecDir = os.path.abspath(os.curdir)
    try:
        os.chdir(path)

        if fakeChangingCalls:
            f = os.popen("echo mvn release:prepare")
        else:
            f = os.popen("mvn release:prepare")
        co = f.read()
        print(co)
        os.chdir(appExecDir)
    except FileNotFoundError as e:
        print("[WARNING] Can't open directory %s, skipping branch prepare. Chances are the branch creation or the checkout of it failed." % path)

def mavenReleasePerformBranch(path) :
    print("releasePrepareBranch(%s)" % path)

    appExecDir = os.path.abspath(os.curdir)
    try:
        os.chdir(path)

        if fakeChangingCalls:
            f = os.popen("echo mvn release:perform")
        else:
            f = os.popen("mvn release:perform")
        co = f.read()
        print(co)

        os.chdir(appExecDir)
    except FileNotFoundError as e:
        print("[WARNING] Can't open directory %s, skipping branch perform. Chances are the branch creation or the checkout of it failed." % path)

def mavenReleaseBranch(path, newBranchName, newDevelopmentVersion) :

    appExecDir = os.path.abspath(os.curdir)
    try:
        os.chdir(path)

        if fakeChangingCalls:
            f = os.popen("echo mvn release:branch -DbranchName=%s -DdevelopmentVersion=%s" % (newBranchName, newDevelopmentVersion))
        else:
            f = os.popen("mvn release:branch -DbranchName=%s -DdevelopmentVersion=%s" % (newBranchName, newDevelopmentVersion))
        co = f.read()
        print(co)

        os.chdir(appExecDir)
    except FileNotFoundError as e:
        print("[WARNING] Can't open directory %s, skipping branching." % path)

if __name__ == '__main__':
    ET.register_namespace("", "http://maven.apache.org/POM/4.0.0")
    main(sys.argv[1:])