Compile function SRP_Git_Services(@Service, @Params)
/************************************************************************************************
    This program is proprietary and is not to be used by or disclosed to others, nor is it to
    be copied without written permission from SRP Computer Solutions, Inc.

    Name        : SRP_GIT_SERVICES
    Test
    Description : Service module for the SRP GIT system.

    Parameters:
        Service [IN] - The service to execute
        Params  [IN] - Service specific parameters

    History (Date, Initials, Notes)
        02/25/19    DJS    Original programmer
        07/29/19    KRF    Ported from Git_Services
        03/04/24    KRF    Fixed bug in PullEntities where For Loop iterator was getting reset
                           by gosubs
************************************************************************************************/
#pragma precomp SRP_PreCompiler

Common /SRP_Git_Services/ SRPGitServices_UserSettings@
Common /SRP_Git_Listener/ SRPGitListener_Suppress@

$insert LOGICAL
$insert MESSAGE_BOX_EQUATES
$insert RLIST_EQUATES

Equ CRLF$ to \0D0A\

Equ SrpGitEnabled$             To 1
Equ SrpGitRepoLoc$             To 2
Equ SrpGitExePath$             To 3
Equ SrpGitGUICommand$          To 4
Equ SrpGitCommitCommand$       To 5
Equ SrpGitPullCommand$         To 6
Equ SrpGitPushCommand$         To 7
Equ SrpGitHistCommand$         To 8
Equ SrpGitDiffCommand$         To 9
Equ SrpGitWarning$             To 10

Declare function SRP_Git_Services, SRP_Git_Serializer, Get_Repos_Entities, Repository, SRP_Editor_Parse, SRP_RevErrorMsg, SRP_Array, Min, DateTime
Declare subroutine SRP_Git_Serializer, Utility, Get_Status, Set_Status, Repository, Msg, Set_Property, Send_Message, Yield, SRP_Git_Services

// load the settings on the first call
If Len(SRPGitServices_UserSettings@) else
    SRPGitServices_UserSettings@ = Xlate("SYSENV", "SRP_GIT_SETTINGS", "", "X")
    If Len(SRPGitServices_UserSettings@) else
        SRPGitServices_UserSettings@ = Xlate("SYSENV", "SRP_GIT_SETTINGS*":@APPID<1>:"*":@Username, "", "X")
    end
end

GoToService

Return Response or ""

//-----------------------------------------------------------------------------
// SERVICES
//-----------------------------------------------------------------------------

Service HasSettings()
    Response = Len(SRPGitServices_UserSettings@<SrpGitRepoLoc$>) GT 0 AND Len(SRPGitServices_UserSettings@<SrpGitExePath$>) GT 0
end service

Service IsEnabled()
    Response = If Len(SRPGitServices_UserSettings@<SrpGitEnabled$>) then SRPGitServices_UserSettings@<SrpGitEnabled$> else 0
end service

Service GetRepoPath()
    Response = SRPGitServices_UserSettings@<SrpGitRepoLoc$>
end service

Service GetGitPath()
    Response = SRPGitServices_UserSettings@<SrpGitExePath$>
end service

Service GetGuiCommand()
    Response = SRPGitServices_UserSettings@<SrpGitGUICommand$>
end service

Service GetCommitCommand()
    Response = SRPGitServices_UserSettings@<SrpGitCommitCommand$>
end service

Service GetPullCommand()
    Response = SRPGitServices_UserSettings@<SrpGitPullCommand$>
end service

Service GetPushCommand()
    Response = SRPGitServices_UserSettings@<SrpGitPushCommand$>
end service

Service GetHistCommand()
    Response = SRPGitServices_UserSettings@<SrpGitHistCommand$>
end service

Service GetDiffCommand()
    Response = SRPGitServices_UserSettings@<SrpGitDiffCommand$>
end service

Service GetWarning()
    Response = SRPGitServices_UserSettings@<SrpGitWarning$>
end service

Service GetCurrentCommit()

    If Len(SRPGitServices_UserSettings@<SrpGitExePath$>) then
        Root = SRPGitServices_UserSettings@<SrpGitExePath$>:' -C "':SRPGitServices_UserSettings@<SrpGitRepoLoc$>:'"'
        Cmd = Root:" for-each-ref --count=1 --sort=-committerdate refs/heads --format=%(HEAD)":\0D\:"%(objectname:short=8)":\0D\:"%(refname:short)":\0D\:"%(committerdate:relative)":\0D\:"%(authorname)":\0D\:"%(subject)":\0D\:"[%(refname:short)]":\0B\:"%(subject)":\0B\:"(%(authorname))"
        Output = "VAR"
        Call SRP_Run_Command(Cmd, Output)
        Convert \0D0B\ to @FM:" " in Output
        Response = Field(Output, @FM, 1, 7)
    end
    
end service

Service GetBranchHeads()
    
    If Len(SRPGitServices_UserSettings@<SrpGitExePath$>) then
        Root = SRPGitServices_UserSettings@<SrpGitExePath$>:' -C "':SRPGitServices_UserSettings@<SrpGitRepoLoc$>:'"'
        Cmd = Root:" for-each-ref --sort=-committerdate refs/heads --format=%(HEAD)":\0D\:"%(objectname:short=8)":\0D\:"%(refname:short)":\0D\:"%(committerdate:relative)":\0D\:"%(authorname)":\0D\:"%(subject)":\0D\:"[%(refname:short)]":\0B\:"%(subject)":\0B\:"(%(authorname))"
        Response = "VAR"
        Call SRP_Run_Command(Cmd, Response)
        Convert \0A0D0B\ to @FM:@VM:" " in Response
        If Response[-1, 1] EQ @FM then Response[-1, 1] = ""
    end
    
end service

Service GetCommits()
    
    If Len(SRPGitServices_UserSettings@<SrpGitExePath$>) then
        Root = SRPGitServices_UserSettings@<SrpGitExePath$>:' -C "':SRPGitServices_UserSettings@<SrpGitRepoLoc$>:'"'
        Cmd = Root:" for-each-ref --sort=-committerdate refs --format=%(HEAD)":\0D\:"%(objectname:short=8)":\0D\:"%(refname:short)":\0D\:"%(committerdate:relative)":\0D\:"%(authorname)":\0D\:"%(subject)":\0D\:"[%(refname:short)]":\0B\:"%(subject)":\0B\:"(%(authorname))"
        Response = "VAR"
        Call SRP_Run_Command(Cmd, Response)
        Convert \0A0D0B\ to @FM:@VM:" " in Response
        If Response[-1, 1] EQ @FM then Response[-1, 1] = ""
    end
        
end service

Service LoadLastCommit()
    Response = Xlate("SYSENV", "SRP_GIT_LASTCOMMIT", "", "X")
end service

Service SaveLastCommit(CommitId, CommitDesc, CommitBranch, CommitAuthor)
    Open "SYSENV" to hSYSENV then
        Rec = ""
        Rec<-1> = CommitId
        Rec<-1> = CommitDesc
        Rec<-1> = CommitBranch
        Rec<-1> = CommitAuthor
        Write Rec to hSYSENV, "SRP_GIT_LASTCOMMIT" then NULL
    end
end service

Service GetFileChanges(StartCommit, EndCommit)
    
    Equ StatusName$ to "Added,Deleted,Modified"
    Response = ""
    ExePath = SRPGitServices_UserSettings@<SrpGitExePath$>
    RepoPath = SRPGitServices_UserSettings@<SrpGitRepoLoc$>
    If Len(ExePath) then
        Cmd = ExePath:' -C "':RepoPath:'" diff --name-status --no-renames --diff-filter=crtuxb ':StartCommit:' ':EndCommit
        Output = "VAR"
        Call SRP_Run_Command(Cmd, Output)
        If RepoPath[-1, 1] NE '\' then RepoPath := '\'
        For Each Line in Output using \0A\
            Status = Line[1, \09\]
            File = Line[Col2() + 1, \09\]
            If IndexC(File, ".gitignore", 1) EQ 0 then
                Pos = Index("ADM", Status[1, 1], 1)
                If Pos GT 0 then Status = Field(StatusName$, ",", Pos, 1) else Status = "Unknown"
                EntId = SRP_Git_Serializer("PathToEntityId", RepoPath, RepoPath:File)
                Response<-1> = Status:@VM:EntId
            end
        Next Line
    end
    
end service

Service SaveUserSettings(GitEnabled, GitRepoLoc, GitExePath, GitGUICommand, GitWarning, GitCommitCommand, GitPullCommand, GitPushCommand, GitHistCommand, GitDiffCommand)

    // Update the settings
    SRPGitServices_UserSettings@<SrpGitEnabled$> = GitEnabled
    SRPGitServices_UserSettings@<SrpGitRepoLoc$> = GitRepoLoc
    SRPGitServices_UserSettings@<SrpGitExePath$> = GitExePath
    SRPGitServices_UserSettings@<SrpGitGUICommand$> = GitGUICommand
    SRPGitServices_UserSettings@<SrpGitWarning$> = GitWarning
    SRPGitServices_UserSettings@<SrpGitCommitCommand$> = GitCommitCommand
    SRPGitServices_UserSettings@<SrpGitPullCommand$> = GitPullCommand
    SRPGitServices_UserSettings@<SrpGitPushCommand$> = GitPushCommand
    SRPGitServices_UserSettings@<SrpGitHistCommand$> = GitHistCommand
    SRPGitServices_UserSettings@<SrpGitDiffCommand$> = GitDiffCommand

    // Write the settings to disk
    Open 'SYSENV' to hSYSENV then
        Write SRPGitServices_UserSettings@ on hSYSENV, "SRP_GIT_SETTINGS" else
            Response = "Failed to save user Git settings. OpenInsight error code: ":Status()
        end
    end
    
    // Update the MD table base on whether or not things are enabled
    Open "MD" to hMD then
        If GitEnabled then
            Read Rec from hMD, "REPOSITORY" else
                Rec = 'P':@FM:@FM:@FM:@FM:'SYSOBJ':@FM:'SRP_GIT_LISTENER'
                Write Rec to hMD, "REPOSITORY" then null
            end
        end else
            Delete hMD, "REPOSITORY" then null
        end
        GarbageCollect
        Flush
        Call Set_Property("SYSTEM", "IDLEPROC", "RTP27":@FM:"REPOSITORY")
    end
    
end service

Options ENTITY_TYPES = "ALL", "OIWIN", "STPROC", "STPROCINS"

Service GetSupportedEntityTypes()
    
    Response = SRP_Git_Serializer("GetSupportedEntityTypes")
    
end service

Service GetOIEntities(EntityTypes=ENTITY_TYPES, Apps)
    
    Response = ""
    If EntityTypes EQ "" OR EntityTypes EQ "ALL" then EntityTypes = SRP_Git_Services("GetSupportedEntityTypes")
    If Apps EQ "" then Apps = @APPID
    For each EntityType in EntityTypes using @FM
        For each App in Apps
            EntList = Get_Repos_Entities(App, EntityType, '')
            If Len(EntList) then
                For each EntID in EntList using @FM
                    Parts = EntID
                    Convert '*' to @VM in Parts
                    Response := EntID:@VM:Parts:@FM ; *:@VM:LastChanged:@FM
                Next EntID
            end
        Next App
    Next EntityType
    Response[-1, 1] = ""
    
end service

Service GetRepoEntities(EntityTypes=ENTITY_TYPES, Apps, CommitStart, CommitEnd)

    // get the repo path
    RepoPath = SRPGitServices_UserSettings@<SrpGitRepoLoc$>
    If RepoPath[-1, 1] NE '\' then RepoPath := '\'
    
    Response = ""
    If EntityTypes EQ "" OR EntityTypes EQ "ALL" then EntityTypes = SRP_Git_Services("GetSupportedEntityTypes")
    If Apps EQ "" then Apps = @APPID
        
    If Len(CommitStart) AND Len(CommitEnd) then
        FileChanges = SRP_Git_Services("GetFileChanges", CommitStart, CommitEnd)
        For Each FileChange in FileChanges
            Status = FileChange<1, 1>
            EntId = FileChange<1, 2>
            Parts = EntId
            Convert '*' to @VM in Parts
            Locate Parts<1, 1> in Apps using @FM setting AppPos then
                Locate Parts<1, 2> in EntityTypes using @FM setting TypePos then
                    Response := EntId:@VM:Parts:@VM:Status:@FM
                end
            end
        Next FileChange
    end else
        For each EntityType in EntityTypes using @FM
            For each App in Apps
                ErrCode = ''
                Type = EntityType[1, '*']
                Class = EntityType[Col2() + 1, '*']        
                WinDir = If Len(Class) then RepoPath:App:'\':Type:'\':Class else RepoPath:App:'\':Type
                Call SetInitDirOptions("D")
                InitDir WinDir:'\*.*'
                DirList = DirList()
                NumDirs = DCount(DirList, @FM)
                For iDir = 1 to NumDirs
                    Dir = DirList<iDir>
                    If Dir NE ".." then
                        CurrPath = If Dir EQ "." then WinDir else WinDir:"\":Dir
                        InitDir CurrPath:'\*.*'
                        FileList = DirList()
                        If Len(FileList) then
                            For each Filename in FileList using @FM setting fPos
                                EntID = SRP_Git_Serializer("PathToEntityId", RepoPath, CurrPath:'\':Filename)
                                Parts = EntID
                                Convert '*' to @VM in Parts
                                Response := EntID:@VM:Parts:@FM
                            Next Filename
                        end
                    end
                Next iDir
            Next App
        Next EntityType
    end
    Response[-1, 1] = ""
     
return

Service PushEntities(EntityList, StatusCtrl)

    OSWrite "" to "SRPGitLog.txt"
    LogPos = 0
    SRPGitListener_Suppress@ = 1
    RepoPath = SRPGitServices_UserSettings@<SrpGitRepoLoc$>

    NumEntities = DCount(EntityList, @FM)
    SRP_Git_Services("SendStatus", StatusCtrl, "Pushing ":NumEntities:" entities.\n", "", LogPos)
    For i = 1 to NumEntities
        EntityId = EntityList<i>
        SRP_Git_Services("SendStatus", StatusCtrl, EntityId, "", LogPos)
        If Field(EntityId, "*", 2, 1) EQ "APPROW" then
            Name = EntityId[-1, "B*"]
            Table = Name[1, ":"]
            Open Table to hTable then
                Key = Xlate("SYSREPOS", EntityId, 4, "X")
                If Len(Key) else Key = Name[Col2() + 1, Len(Name)]
                Read Record from hTable, Key then
                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Pushed\n", "", LogPos)
                    SRP_Git_Serializer("WriteSync", EntityId, Record, RepoPath, Key)
                end else
                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Push Failed\n    Unable to read SYSREPOS, ":Key:".\n", "", LogPos)
                end
            end else
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Push Failed\n    Unable to open SYSREPOS.\n", "", LogPos)
            end
        end else
            Set_Status(0)
            Record = Repository("ACCESS", EntityId)
            If Get_Status(ErrCode) then
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Push Failed\n", ErrCode, LogPos)
            end else
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Pushed\n", "", LogPos)
                SRP_Git_Serializer("WriteSync", EntityId, Record, RepoPath)
            end
        end
    Next i
    
    SRPGitListener_Suppress@ = ""
    
end service

Service PullEntities(EntityList, StatusList, StatusCtrl, CommitId) 

    OSWrite "" to "SRPGitLog.txt"
    LogPos = 0
    SRPGitListener_Suppress@ = 1
    ExePath = SRPGitServices_UserSettings@<SrpGitExePath$>
    RepoPath = SRPGitServices_UserSettings@<SrpGitRepoLoc$>

    EntitiesToCompile = ''
    NumEntities = DCount(EntityList, @FM)
    SRP_Git_Services("SendStatus", StatusCtrl, "Pulling ":NumEntities:" entities.\n", "", LogPos)
    For iEntityToPull = 1 to NumEntities
        EntityId = EntityList<iEntityToPull>
        Status = StatusList<iEntityToPull>
        App = EntityId[1, "*"]
        Type = EntityId[Col2() + 1, "*"]
        Class = EntityId[Col2() + 1, "*"]
        Name = EntityId[Col2() + 1, "*"]
        SRP_Git_Services("SendStatus", StatusCtrl, EntityId, "", LogPos)
        If Status _EQC "Deleted" then
            If Type EQ "APPROW" then
                Table = Name[1, ":"]
                Key = Xlate("SYSREPOS", EntityId, 4, "X")
                If Len(Key) else Key = Name[Col2() + 1, Len(Name)]
                Open Table to hTable then
                    Lock hTable, Key then
                        Unlock hTable, Key
                        Delete hTable, Key then
                            Open "SYSREPOS" to hTable then
                                Delete hTable, EntityID then null
                            end else
                                SRP_Git_Services("SendStatus", StatusCtrl, " -- Delete Failed\n", Status(), LogPos)
                            end
                        end else
                            SRP_Git_Services("SendStatus", StatusCtrl, " -- Delete Failed\n", Status(), LogPos)
                        end
                    end else
                        SRP_Git_Services("SendStatus", StatusCtrl, " -- Delete Failed\n    Locked or Doesn't Exist!\n", "", LogPos)
                    end
                end else
                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Delete Failed\n", Status(), LogPos)
                end
            end else
                If App EQ @APPID<1> then
                    Set_Status(0)
                    Repository("DESTROY", EntityId)
                end else
                    GoSub DeleteInherited
                end
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Deleted\n", "", LogPos)
            end
        end else

            // Get the file from git
            Path = SRP_Git_Serializer("EntityIdToRelativePath", EntityId)
            Convert "\" to "/" in Path
            Cmd = ExePath:' -C "':RepoPath:'" show ':CommitId:':':Path
            FileData = "VAR"
            Call SRP_Run_Command(Cmd, FileData)
            
            // If it didn't work, just read it if possible
            ErrCode = 0
            If FileData[1, 7] EQ "fatal: " then
                Convert "/" to "\" in Path
                OSRead FileData from RepoPath:"\":Path else
                    ErrCode = Status()
                end
            end
            
            If ErrCode EQ 0 then
                
                Metadata = ""
                Record = SRP_Git_Serializer("Deserialize", EntityId, FileData, Metadata)
                
                If Len(Record) else Record = " "
                If Type EQ "APPROW" then
                    Table = Name[1, ":"]
                    If Metadata NE '' then
                    	Key = Metadata
                    end else
                    	Key = Name[Col2() + 1, Len(Name)]
                    end
                    Open Table to hTable then
                        Write Record to hTable, Key then
                            Open "SYSREPOS" to hSYSREPOS then
                                Read RepoRec from hSYSREPOS, EntityId else
                                    RepoRec    = App
                                    RepoRec<2> = "$PUBLIC"
                                    RepoRec<3> = "$PUBLIC"
                                    RepoRec<4> = Key
                                    RepoRec<18> = "0"
                                    RepoRec<20> = "0"
                                    RepoRec<21> = "1"
                                    RepoRec<22> = "0"
                                    RepoRec<23> = "0"
                                    RepoRec<26> = App
                                    RepoRec<27> = Key
                                end
                                RepoRec<25> = DateTime()
                                Write RepoRec to hSYSREPOS, EntityId then
                                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Saved\n", "", LogPos)
                                end else
                                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n", Status(), LogPos)
                                end
                            end else
                                SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n", Status(), LogPos)
                            end
                        end else
                            SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n", Status(), LogPos)
                        end
                    end else
                        SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n", Status(), LogPos)
                    end
                end else
                    If App EQ @APPID<1> then
                        Set_Status(0)
                        Repository("LOCK", EntityId)
                        If Get_Status(ErrCode) then
                            SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n    Locked!\n", "", LogPos)
                        end else
                        	Set_Status(0)
							Repository("WRITE", EntityId, "", 1, 1, "", "", "", "", "", EntityId[-1, "B*"], Record)
							If Get_Status(ErrCode) then
								Set_Status(0)
								Repository("NEW", EntityId, "", 1, 1, "", "", "", "", "", EntityId[-1, "B*"], Record)
								If Get_Status(ErrCode) then
									SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n", ErrCode, LogPos)
								end else
									SRP_Git_Services("SendStatus", StatusCtrl, " -- Saved\n", "", LogPos)
									Get_Status(ErrCode)
									If Type EQ "STPROC" OR Type EQ "OIWIN" OR Type EQ "OIEVENT" then EntitiesToCompile := EntityId:@FM											
								end
							end else
								SRP_Git_Services("SendStatus", StatusCtrl, " -- Saved\n", "", LogPos)
								Get_Status(ErrCode)
								If Type EQ "STPROC" OR Type EQ "OIWIN" OR Type EQ "OIEVENT" then EntitiesToCompile := EntityId:@FM
							end                                	
                            Set_Status(0)
                            Repository("UNLOCK", EntityId)
                        end
                    end else
                        GoSub WriteInherited
                    end
                end
                
            end else
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n", ErrCode, LogPos)
            end
        end
    Next iEntityToPull
    EntitiesToCompile[-1, 1] = ""
    
    NumEntities = DCount(EntitiesToCompile, @FM)
    If NumEntities GT 0 then
        SRP_Git_Services("SendStatus", StatusCtrl, "\nCompiling ":NumEntities:" entities.\n", "", LogPos)
        For Each EntityId in EntitiesToCompile
            SRP_Git_Services("SendStatus", StatusCtrl, EntityId, "", LogPos)
            App = EntityId[1, "*"]
            If App EQ @APPID<1> then
                Set_Status(0)
                Repository("COMPILE", EntityId, 1)
                If Get_Status(ErrCode) then
                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Compile Errors\n", ErrCode, LogPos)
                end else
                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Compile Successful\n", "", LogPos)
                end
            end else
                GoSub CompileInherited
            end
        Next EntityId
    end else
        SRP_Git_Services("SendStatus", StatusCtrl, "\nNo entities to compile.\n", "", LogPos)
    end
    SRPGitListener_Suppress@ = ""
      
end service

Service OpenRepo()
    
    Name = "GUI"
    CmdPos = SrpGitGUICommand$
    GoSub RunGitCommand
    If Assigned(ErrorMsg) then
        If Len(ErrorMsg) then Msg(@Window, ErrorMsg:@FM:@FM:@FM:"!")
    end
    
end service

Service Commit()
    
    Name = "Commit"
    CmdPos = SrpGitCommitCommand$
    GoSub RunGitCommand
    
end service

Service Pull()
    
    Name = "Pull"
    CmdPos = SrpGitPullCommand$
    GoSub RunGitCommand
    
end service

Service Push()
    
    Name = "Push"
    CmdPos = SrpGitPushCommand$
    GoSub RunGitCommand
    
end service

Service ViewHist()
    
    Name = "ViewHist"
    CmdPos = SrpGitHistCommand$
    GoSub RunGitCommand
    
end service

Service Diff()
    
    Name = "Diff"
    CmdPos = SrpGitDiffCommand$
    GoSub RunGitCommand
    
end service

Service SendStatus(StatusCtrl, Text, ErrCode, Ref Pos)
    
    Swap "\n" with CRLF$ in Text
    
    OSOpen "SRPGitLog.txt" to hFile else hFile = ""
    
    If Len(StatusCtrl) then
        Send_Message(StatusCtrl, "INSERT", -1, Text)
        If Len(hFile) then
            OSBWrite text on hFile at Pos
            Pos += Len(Text)
        end
        If Len(ErrCode) then
            For Each ErrorInfo in ErrCode using @FM
                Text = "    ":SRP_RevErrorMsg(ErrorInfo[1, @VM], ErrorInfo[Col2() + 1, Len(ErrorInfo)]):CRLF$
                Swap "__SRP_GIT_TEMP" with "" in Text
                Send_Message(StatusCtrl, "INSERT", -1, Text)
                If Len(hFile) then
                    OSBWrite text on hFile at Pos
                    Pos += Len(Text)
                end
            Next ErrorCode
        end
        Yield()
    end
    
    If Len(hFile) then OSClose hFile
    
end service

RunGitCommand:
    
    ErrorList = ''
    If SRPGitServices_UserSettings@<SrpGitEnabled$> EQ True$ then
        Command = SRPGitServices_UserSettings@<CmdPos>
        RepoPath = SRPGitServices_UserSettings@<SrpGitRepoLoc$>
        If Command NE '' then
            If RepoPath NE '' then
                Utility("RUNWIN", Command, 1)
            end else
                // User has not set the Git repository location
                ErrorMsg = "Git repository location has not been defined within Git Settings"
                ErrorList<-1> = ErrorMsg
            end
        end else
            // User has not set the Git open repo command (Git GUI command)
            ErrorMsg = "Git ":Name:" command has not been configured within Git Settings"
            ErrorList<-1> = ErrorMsg
        end       
    end else
        // User has Git disabled
        ErrorMsg = "Git must first be enabled within Git Settings"
        ErrorList<-1> = ErrorMsg
    end
    Response = ErrorList
    
return

CompileInherited:
// IN: EntityId

    // Read the original source record
    DestList = SRP_Git_Serializer("EntityIdToKeys", EntityId)
    Record = Xlate(DestList<1, 1>, DestList<1, 2>, "", "X")
    
    // Build a temporary entity in the current app
    TempId = @APPID<1>:"*":Field(EntityID, "*", 2, 3):"__SRP_GIT_TEMP"
    Type = Field(EntityId, "*", 2, 1)
    
    // If this is a stored procedure or insert, we need to rename it temporarily IN THE CODE
    FirstLine = Record<1>
    If Type[1, 6] _EQC "STPROC" AND Len(Xlate("SYSOBJ", "$SRP_EDITOR_PARSE", "", "X")) then
        ProcType = If Type _EQC "STPROCINS" then "Insert" else "Procedure"
        OrigProcName = ""
        If SRP_Editor_Parse(FirstLine, "", ProcType, OrigProcName, "") then
            TempName = Field(TempId, "*", 4)
            TempFirstLine = FirstLine[1, "("]
            Swap OrigProcName with TempName in TempFirstLine
            If ProcType EQ "Insert" then
                Record<1> = TempFirstLine
            end else
                Record<1> = TempFirstLine:"(":FirstLine[-1, "B("]
            end
        end
    end
    
    // Update it and compile it
    SRPGitListener_Suppress@ = 1
    Set_Status(0)
    Repository("WRITE", TempID, "", 1, 1, "", "", "", "", "", TempID[-1, "F*"], Record)
    If Get_Status(ErrCode) then
        SRP_Git_Services("SendStatus", StatusCtrl, " -- Failed to create Temprorary Entity.\n", ErrCode, LogPos)
    end else
        Set_Status(0)
        Repository("COMPILE", TempId)
        If Get_Status(ErrCode) then
            SRP_Git_Services("SendStatus", StatusCtrl, " -- Compile Errors\n", ErrCode, LogPos)
        end else
            SRP_Git_Services("SendStatus", StatusCtrl, " -- Compile Successful\n", "", LogPos)
            // Copy the temporary records back to the entity records
            SourceList = SRP_Git_Serializer("EntityIdToKeys", TempId)
            NumItems = DCount(SourceList, @FM)
            For i = 1 to NumItems
                Table = SourceList<i, 1>
                SourceKey = SourceList<i, 2>
                DestKey = DestList<i, 2>
                If SourceKey NE DestKey then
                    Open Table to hTable then
                        Read Rec from hTable, SourceKey then
                            If Table EQ "SYSPROCS" then Rec<1> = FirstLine
                            Swap TempID with EntityID in Rec
                            Write Rec to hTable, DestKey then null
                        end
                    end
                end
            Next i
        end
    end
    
    // Delete the local copy
    Set_Status(0)
    Repository("DESTROY", TempId)
    SRPGitListener_Suppress@ = ""
    
return

WriteInherited:
// IN: EntityId, Record
    
    // Delete the actual records
    DestList = SRP_Git_Serializer("EntityIdToKeys", EntityId)
    Table = DestList<1, 1>
    DestKey = DestList<1, 2>
    Open Table to hTable then
        Lock hTable, DestKey then
            Write Record to hTable, DestKey then
                
                // Update or create the SYSREPOS record at the correct app level
                Open "SYSREPOS" to hSYSREPOS then
                    RepoKey = DestList[-1, "B":@VM]
                    Read RepoRec from hSYSREPOS, RepoKey else
                        RepoRec    = App
                        RepoRec<2> = "$PUBLIC"
                        RepoRec<3> = "$PUBLIC"
                        RepoRec<18> = "0"
                        RepoRec<20> = "1"
                        RepoRec<21> = "1"
                        RepoRec<22> = "0"
                        RepoRec<23> = "1"
                        RepoRec<26> = App
                        RepoRec<27> = "Y"
                    end
                    RepoRec<24> = EntityId:"*":DateTime()
                    RepoRec<25> = DateTime()
                    Write RepoRec to hSYSREPOS, RepoKey then null
                end
                
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Saved\n", "", LogPos)
                If Type EQ "STPROC" OR Type EQ "OIWIN" OR Type EQ "OIEVENT" then EntitiesToCompile := EntityId:@FM
            end
            Unlock hTable, DestKey
        end else
            SRP_Git_Services("SendStatus", StatusCtrl, " -- Save Failed\n    Locked!\n", "", LogPos)
        end
    end
    
return

DeleteInherited:
// IN: EntityId, Record
       
    // Delete the actual records
    DestList = SRP_Git_Serializer("EntityIdToKeys", EntityId)
    NumItems = DCount(DestList, @FM)
    For i = 1 to NumItems
        Table = DestList<i, 1>
        DestKey = DestList<i, 2>
        Open Table to hTable then
            Lock hTable, DestKey then
                Delete hTable, DestKey then
                    SRP_Git_Services("SendStatus", StatusCtrl, " -- Deleted\n", "", LogPos)
                end
                Unlock hTable, DestKey
            end else
                SRP_Git_Services("SendStatus", StatusCtrl, " -- Delete Failed\n    Locked!\n", "", LogPos)
            end
        end
    Next i
    
return
