# Generated by Haxe 4.3.7
# coding: utf-8
import sys

import re as python_lib_Re


class _hx_AnonObject:
    _hx_disable_getattr = False
    def __init__(self, fields):
        self.__dict__ = fields
    def __repr__(self):
        return repr(self.__dict__)
    def __contains__(self, item):
        return item in self.__dict__
    def __getitem__(self, item):
        return self.__dict__[item]
    def __getattr__(self, name):
        if (self._hx_disable_getattr):
            raise AttributeError('field does not exist')
        else:
            return None
    def _hx_hasattr(self,field):
        self._hx_disable_getattr = True
        try:
            getattr(self, field)
            self._hx_disable_getattr = False
            return True
        except AttributeError:
            self._hx_disable_getattr = False
            return False



class EReg:
    __slots__ = ("pattern", "matchObj", "_hx_global")

    def __init__(self,r,opt):
        self.matchObj = None
        self._hx_global = False
        options = 0
        _g = 0
        _g1 = len(opt)
        while (_g < _g1):
            i = _g
            _g = (_g + 1)
            c = (-1 if ((i >= len(opt))) else ord(opt[i]))
            if (c == 109):
                options = (options | python_lib_Re.M)
            if (c == 105):
                options = (options | python_lib_Re.I)
            if (c == 115):
                options = (options | python_lib_Re.S)
            if (c == 117):
                options = (options | python_lib_Re.U)
            if (c == 103):
                self._hx_global = True
        self.pattern = python_lib_Re.compile(r,options)



class Std:
    __slots__ = ()

    @staticmethod
    def parseInt(x):
        if (x is None):
            return None
        _hx_len = len(x)
        index = 0
        while (index < _hx_len):
            if (not (x[index] in " \n\r\t\x0B\x0C")):
                break
            index = (index + 1)
        isNegative = None
        if (index < _hx_len):
            sign = x[index]
            if ((sign == "-") or ((sign == "+"))):
                index = (index + 1)
            isNegative = (sign == "-")
        else:
            isNegative = False
        isHexadecimal = None
        if ((index + 1) < _hx_len):
            cur = x[index]
            next = x[(index + 1)]
            isHexadecimal = ((cur == "0") and (((next == "x") or ((next == "X")))))
        else:
            isHexadecimal = False
        if isHexadecimal:
            index = (index + 2)
        cur = index
        if isHexadecimal:
            while (cur < _hx_len):
                if (not (x[cur] in "0123456789abcdefABCDEF")):
                    break
                cur = (cur + 1)
        else:
            while (cur < _hx_len):
                if (not (x[cur] in "0123456789")):
                    break
                cur = (cur + 1)
        firstInvalidIndex = cur
        if (index == firstInvalidIndex):
            return None
        result = int(HxString.substring(x,index,firstInvalidIndex),(16 if isHexadecimal else 10))
        if isNegative:
            return -result
        else:
            return result


class StringTools:
    __slots__ = ()

    @staticmethod
    def isSpace(s,pos):
        if (((len(s) == 0) or ((pos < 0))) or ((pos >= len(s)))):
            return False
        c = HxString.charCodeAt(s,pos)
        if (not (((c > 8) and ((c < 14))))):
            return (c == 32)
        else:
            return True

    @staticmethod
    def ltrim(s):
        l = len(s)
        r = 0
        while ((r < l) and StringTools.isSpace(s,r)):
            r = (r + 1)
        if (r > 0):
            return HxString.substr(s,r,(l - r))
        else:
            return s

    @staticmethod
    def rtrim(s):
        l = len(s)
        r = 0
        while ((r < l) and StringTools.isSpace(s,((l - r) - 1))):
            r = (r + 1)
        if (r > 0):
            return HxString.substr(s,0,(l - r))
        else:
            return s

    @staticmethod
    def trim(s):
        return StringTools.ltrim(StringTools.rtrim(s))


class core_Main:
    __slots__ = ()

    @staticmethod
    def main():
        pass

    @staticmethod
    def getCommitTypes():
        return ["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test"]

    @staticmethod
    def parseCommit(commit,isIssueRequired = None):
        if (isIssueRequired is None):
            isIssueRequired = True
        parsedCommit = core_Main.parse(commit,isIssueRequired)
        if ((parsedCommit is None) or (not core_Main.isValidType(parsedCommit))):
            return None
        return parsedCommit

    @staticmethod
    def isCommitValid(commit,isIssueRequired = None):
        if (isIssueRequired is None):
            isIssueRequired = True
        parsedCommit = core_Main.parse(commit,isIssueRequired)
        if (parsedCommit is not None):
            return core_Main.isValidType(parsedCommit)
        else:
            return False

    @staticmethod
    def buildCommit(commit):
        commitString = commit.type
        if (commit.scope != ""):
            commitString = (("null" if commitString is None else commitString) + HxOverrides.stringOrNull(((("(" + HxOverrides.stringOrNull(commit.scope)) + ")"))))
        if commit.breakChange:
            commitString = (("null" if commitString is None else commitString) + "!")
        commitString = (("null" if commitString is None else commitString) + HxOverrides.stringOrNull((((((": " + HxOverrides.stringOrNull(commit.description)) + " (#") + str(commit.issue)) + ")"))))
        return commitString

    @staticmethod
    def isValidType(commit):
        return (python_internal_ArrayImpl.indexOf(core_Main.getCommitTypes(),commit.type,None) != -1)

    @staticmethod
    def parse(commit,parseIssue = None):
        if (parseIssue is None):
            parseIssue = True
        commit = StringTools.trim(commit)
        startIndex = None
        colonIndex = (commit.find(":") if ((startIndex is None)) else HxString.indexOfImpl(commit,":",startIndex))
        if (colonIndex == -1):
            return None
        head = HxString.substring(commit,0,colonIndex)
        tail = HxString.substring(commit,(colonIndex + 1),None)
        if ((len(tail) == 0) or (not tail.startswith(" "))):
            return None
        tail = StringTools.trim(tail)
        breakChange = False
        if head.endswith("!"):
            if head.endswith("!!"):
                return None
            breakChange = True
            head = HxString.substr(head,0,(len(head) - 1))
        typeStr = head
        scopeStr = ""
        startIndex = None
        openParen = (head.find("(") if ((startIndex is None)) else HxString.indexOfImpl(head,"(",startIndex))
        startIndex = None
        closeParen = (head.find(")") if ((startIndex is None)) else HxString.indexOfImpl(head,")",startIndex))
        if (((openParen != -1) and ((closeParen != -1))) and ((closeParen > openParen))):
            scopeStr = HxString.substr(head,(openParen + 1),((closeParen - openParen) - 1))
            typeStr = HxString.substr(head,0,openParen)
        if ((openParen != -1) and ((closeParen != -1))):
            if (scopeStr == ""):
                return None
            eregScope = EReg("^[a-zA-Z0-9]+(?:[-_][a-zA-Z0-9]+)*$","")
            eregScope.matchObj = python_lib_Re.search(eregScope.pattern,scopeStr)
            if (eregScope.matchObj is None):
                return None
        issueValue = 0
        hasIssue = False
        eregIssue = EReg(" \\(#([1-9]\\d*)\\)$","")
        eregIssue.matchObj = python_lib_Re.search(eregIssue.pattern,tail)
        if (eregIssue.matchObj is not None):
            issueValue = Std.parseInt(eregIssue.matchObj.group(1))
            tail = HxString.substr(tail,0,(len(tail) - len(eregIssue.matchObj.group(0))))
            hasIssue = True
        if (parseIssue and (not hasIssue)):
            return None
        descriptionStr = tail
        if (descriptionStr != ""):
            eregDesc = EReg("^\\w(?:\\w|\\s|[-_',.]|\\[(?:\\w|\\s|[-_])*\\])*$","")
            eregDesc.matchObj = python_lib_Re.search(eregDesc.pattern,descriptionStr)
            if (eregDesc.matchObj is None):
                return None
        else:
            return None
        return _hx_AnonObject({'type': typeStr, 'scope': scopeStr, 'breakChange': breakChange, 'description': descriptionStr, 'issue': issueValue})


class haxe_iterators_ArrayIterator:
    __slots__ = ("array", "current")

    def __init__(self,array):
        self.current = 0
        self.array = array

    def hasNext(self):
        return (self.current < len(self.array))

    def next(self):
        def _hx_local_3():
            def _hx_local_2():
                _hx_local_0 = self
                _hx_local_1 = _hx_local_0.current
                _hx_local_0.current = (_hx_local_1 + 1)
                return _hx_local_1
            return python_internal_ArrayImpl._get(self.array, _hx_local_2())
        return _hx_local_3()



class python_internal_ArrayImpl:
    __slots__ = ()

    @staticmethod
    def indexOf(a,x,fromIndex = None):
        _hx_len = len(a)
        l = (0 if ((fromIndex is None)) else ((_hx_len + fromIndex) if ((fromIndex < 0)) else fromIndex))
        if (l < 0):
            l = 0
        _g = l
        _g1 = _hx_len
        while (_g < _g1):
            i = _g
            _g = (_g + 1)
            if HxOverrides.eq(a[i],x):
                return i
        return -1

    @staticmethod
    def _get(x,idx):
        if ((idx > -1) and ((idx < len(x)))):
            return x[idx]
        else:
            return None


class HxOverrides:
    __slots__ = ()

    @staticmethod
    def eq(a,b):
        if (isinstance(a,list) or isinstance(b,list)):
            return a is b
        return (a == b)

    @staticmethod
    def stringOrNull(s):
        if (s is None):
            return "null"
        else:
            return s


class python_internal_MethodClosure:
    __slots__ = ("obj", "func")

    def __init__(self,obj,func):
        self.obj = obj
        self.func = func

    def __call__(self,*args):
        return self.func(self.obj,*args)



class HxString:
    __slots__ = ()

    @staticmethod
    def charCodeAt(s,index):
        if ((((s is None) or ((len(s) == 0))) or ((index < 0))) or ((index >= len(s)))):
            return None
        else:
            return ord(s[index])

    @staticmethod
    def indexOfImpl(s,_hx_str,startIndex):
        if (_hx_str == ""):
            length = len(s)
            if (startIndex < 0):
                startIndex = (length + startIndex)
                if (startIndex < 0):
                    startIndex = 0
            if (startIndex > length):
                return length
            else:
                return startIndex
        return s.find(_hx_str, startIndex)

    @staticmethod
    def substring(s,startIndex,endIndex = None):
        if (startIndex < 0):
            startIndex = 0
        if (endIndex is None):
            return s[startIndex:]
        else:
            if (endIndex < 0):
                endIndex = 0
            if (endIndex < startIndex):
                return s[endIndex:startIndex]
            else:
                return s[startIndex:endIndex]

    @staticmethod
    def substr(s,startIndex,_hx_len = None):
        if (_hx_len is None):
            return s[startIndex:]
        else:
            if (_hx_len == 0):
                return ""
            if (startIndex < 0):
                startIndex = (len(s) + startIndex)
                if (startIndex < 0):
                    startIndex = 0
            return s[startIndex:(startIndex + _hx_len)]



core_Main.main()
