Function Logging_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        :   Logging_Services

    Description :   Handler program for all module related services.

    Notes       :   The generic parameters should contain all the necessary information to process the services. Often
                    this will be information like the data Record and Key ID.

    Parameters  :
        Service         [in] -- Name of the service being requested
        Param1-10   [in/out] -- Additional request parameter holders
        Response       [out] -- Response to be sent back to the Controller (MCP) or requesting procedure

    Metadata    :

    History     :   (Date, Initials, Notes)
        08/30/17    dmb     Original programmer.
        02/17/18    dmb     Use the new named cache feature of Memory_Services so logging data is protected when other
                            processes release a cache table.

***********************************************************************************************************************/

#pragma precomp SRP_PreCompiler

$insert LOGICAL
$insert SERVICE_SETUP
$insert SRPMail_Inserts

Equ     CRLF$       to \0D0A\
Equ     CR$         to \0D\
Equ     LF$         to \0A\
Equ     TAB$        to \09\
Equ     COMMA$      to ','

Common /LogginServices/ Unused1@, Unused2@, Unused3@, Unused4@, Unused5@, Unused6@, Unused7@, Unused8@

Declare function    Logging_Services, Memory_Services, SRP_Hash, SRP_Path, SRP_Send_Mail, Environment_Services
Declare subroutine  Logging_Services, Memory_Services, SetInitDirOptions

GoToService else
    Error_Services('Add', Service : ' is not a valid service request within the Logging services module.')
end

Return Response OR ''


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Service Parameter Options
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Options BOOLEAN     = True$, False$


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Services
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------------------------------------------------
// NewLog
//
// LogPath          - Path to where the log file is located. - [Required]
// LogFileName      - Name of the log file. - [Required]
// RowDelimiter     - Delimiter used to separate each log row. Default is CR/LF. - [Optional]
// ColumnDelimiter  - Delimiter used to separate each column value. If ColumnWidths is empty then this will default to a
//                    comma. - [Optional]
// ColumnHeaders    - @FM list of Column headers to use in the log file. Default is no column headers will be used.
//                    - [Optional]
// ColumnWidths     - @FM list of Column widths for each column data value. If empty then the entire column value will
//                    be stored. - [Optional]
// QuoteValues      - Boolean flag to indicate if column values should be quoted. Default is false. - [Optional]
// ClearLog         - Boolean flag to indicate if any existing log file should be cleared. Default is false.
//                    - [Optional]
//
// Returns an object handle to a log file.
//----------------------------------------------------------------------------------------------------------------------
Service NewLog(LogPath, LogFileName, RowDelimiter, ColumnDelimiter, ColumnHeaders, ColumnWidths, QuoteValues=BOOLEAN, ClearLog=BOOLEAN)

    objLog      = ''

    If (LogPath NE '') AND (LogFileName NE '') then
        If SRP_Path('Exists', LogPath) then
            LogFullPath = SRP_Path('Combine', LogPath, LogFileName)
            If LogFullPath[1, 1] EQ '\' AND LogFullPath[2, 1] NE '\' then LogFullPath = '\' : LogFullPath
            objLog      = SRP_Hash(LogFullPath, 'SHA-1', 'BASE32')
            Memory_Services('SetValue', objLog : '*LogPath', LogPath, ServiceModule)
            Memory_Services('SetValue', objLog : '*LogFileName', LogFileName, ServiceModule)
            Memory_Services('SetValue', objLog : '*LogFullPath', LogFullPath, ServiceModule)
            If Dir(LogFullPath) NE '' then
                If ClearLog then
                    Logging_Services('CreateLogFile', objLog)
                end
            end else
                Logging_Services('CreateLogFile', objLog)
            end
            If Error_Services('NoError') then
                If RowDelimiter EQ '' then RowDelimiter = CRLF$
                Memory_Services('SetValue', objLog : '*RowDelimiter', RowDelimiter, ServiceModule)
                If (ColumnDelimiter EQ '') AND (ColumnWidths EQ '') then ColumnDelimiter = COMMA$
                Memory_Services('SetValue', objLog : '*ColumnDelimiter', ColumnDelimiter, ServiceModule)
                Memory_Services('SetValue', objLog : '*ColumnHeaders', ColumnHeaders, ServiceModule)
                Memory_Services('SetValue', objLog : '*ColumnWidths', ColumnWidths, ServiceModule)
                If QuoteValues NE True$ then QuoteValues = False$
                Memory_Services('SetValue', objLog : '*QuoteValues', QuoteValues, ServiceModule)
                If Dir(LogFullPath)<1> EQ 0 AND ColumnHeaders NE '' then
                    // Add the column headers since this is a new log file.
                    Logging_Services('AppendLog', objLog, ColumnHeaders, '', @FM, True$)
                end
            end
        end else
            Error_Services('Add', LogPath : ' does not exist.')
        end
    end else
        Error_Services('Add', 'LogPath or LogFileName argument was missing from the ' : Service : ' service.')
    end

    Response    = objLog

end service


//----------------------------------------------------------------------------------------------------------------------
// AppendLog
//
// objLog                   - Object handle to the log file. - [Required]
// LogData                  - Data to be appended to the log file. - [Required]
// IncomingRowDelimiter     - Delimiter used to separate each log row coming in. This allows incoming log data to have
//                            a different delimiter than what will be used in the log file. Default is the RowDelimiter
//                            used for appending the log data. - [Optional]
// IncomingColumnDelimiter  - Delimiter used to separate each column value in the log data. This allows incoming log
//                            data to have a different delimiter than what will be used in the log file. Default is the
//                            column delimiter used to separate the log data or a comma if fixed widths only are
//                            indicated. - [Optional]
// IgnoreColumnHeaders      - Boolean flag to indicate if the service should attempt to add column headers to an empty
//                            log file. Default is false. - [Optional]
// EmailAddresses           - Comma delimited list of email addresses that should be notified when this log is appended.
//                            - [Optional]
// EmailMessage             - Message to be sent to the email addresses.
//
// Appends data to the log file associated with the indicated log object handle.
//----------------------------------------------------------------------------------------------------------------------
Service AppendLog(objLog, LogData, IncomingRowDelimiter, IncomingColumnDelimiter, IgnoreColumnHeaders, EmailAddresses, EmailMessage)

    If (objLog NE '') AND (LogData NE '') then
        If IgnoreColumnHeaders NE True$ then IgnoreColumnHeaders = False$
        LogFullPath     = Logging_Services('GetLogFullPath', objLog)
        ColumnDelimiter = Logging_Services('GetColumnDelimiter', objLog)
        LenColDel       = Len(ColumnDelimiter)
        ColumnHeaders   = Logging_Services('GetColumnHeaders', objLog)
        ColumnWidths    = Logging_Services('GetColumnWidths', objLog)
        QuoteValues     = Logging_Services('GetQuoteValues', objLog)
        RowDelimiter    = Logging_Services('GetRowDelimiter', objLog)
        If IncomingRowDelimiter EQ '' then IncomingRowDelimiter = RowDelimiter
        If (IncomingColumnDelimiter EQ '') AND (ColumnWidths EQ '') then IncomingColumnDelimiter = ColumnDelimiter
        LenRowDel       = Len(RowDelimiter)
        FileInfo        = Dir(LogFullPath)
        FileSize        = FileInfo<1>
        Status()        = 0
        OutData         = ''
        OSOpen LogFullPath to hFile then
            If (FileSize EQ 0) AND (ColumnHeaders NE '') AND (Not(IgnoreColumnHeaders)) then
                Logging_Services('AppendLog', objLog, ColumnHeaders, @RM, @FM, True$)
            end
            For Each RowData in LogData using IncomingRowDelimiter
                If RowData NE '' then
                    For Each ColumnData in RowData using IncomingColumnDelimiter setting cPos
                        If ColumnWidths NE '' then
                            ColumnWidth = ColumnWidths<cPos>
                            ColumnData  = ColumnData[1, ColumnWidth] : Str(' ', ColumnWidth - Len(ColumnData))
                        end
                        If QuoteValues then
                            Swap '"' with '""' in ColumnData    ; // Encode the quotes properly.
                            ColumnData  = Quote(ColumnData)
                        end
                        OutData    := ColumnData : ColumnDelimiter
                    Next ColumnData
                    OutData[Neg(LenColDel), LenColDel]  = ''            ; // Strip off the last column delimiter.
                    OutData                            := RowDelimiter  ; // Append a row delimiter.
                end
            Next LogRow
            OutData[Neg(LenRowDel), LenRowDel]  = ''    ; // Strip off the last row delimiter.
            If (FileSize NE 0) then OutData = RowDelimiter : OutData    ; // Prepend a row delimiter since there is existing data.
            OSBWrite OutData to hFile at FileSize
            OSError = Status()
            If OSError then
                Error_Services('Add', 'OSBWrite error code ' : OSError : ' in the ' : Service : ' service.')
            end
            OSClose hFile
        end else
            OSError = Status()
            Error_Services('Add', 'OSOpen error code ' : OSError : ' in the ' : Service : ' service.')
        end

    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    If EmailAddresses NE '' then
        GoSub EmailMessage
    end
   
end service


//----------------------------------------------------------------------------------------------------------------------
// GetLogPath
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the path for the log file associated with the indicated log object handle. This will not include the name of
// the log file itself.
//----------------------------------------------------------------------------------------------------------------------
Service GetLogPath(objLog)

    LogPath = ''

    If objLog NE '' then
        LogPath = Memory_Services('GetValue', objLog : '*LogPath', '', '', ServiceModule)
        If LogPath EQ '' then
            Error_Services('Add', 'Log path not found in the ' : Service : ' service.')
        end
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = LogPath

end service


//----------------------------------------------------------------------------------------------------------------------
// GetLogFileName
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the file name for the log file associated with the indicated log object handle. This will not include the
// path to where the log file is located.
//----------------------------------------------------------------------------------------------------------------------
Service GetLogFileName(objLog)

    LogFileName = ''

    If objLog NE '' then
        LogFileName = Memory_Services('GetValue', objLog : '*LogFileName', '', '', ServiceModule)
        If LogFileName EQ '' then
            Error_Services('Add', 'Log file name not found in the ' : Service : ' service.')
        end
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = LogFileName

end service


//----------------------------------------------------------------------------------------------------------------------
// GetLogFullPath
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the full path for the log file associated with the indicated log object handle.
//----------------------------------------------------------------------------------------------------------------------
Service GetLogFullPath(objLog)

    LogFullPath = ''

    If objLog NE '' then
        LogFullPath = Memory_Services('GetValue', objLog : '*LogFullPath', '', '', ServiceModule)
        If LogFullPath EQ '' then
            Error_Services('Add', 'Log full path not found in the ' : Service : ' service.')
        end
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = LogFullPath

end service


//----------------------------------------------------------------------------------------------------------------------
// GetRowDelimiter
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the delimiter to use to separate each row in the log.
//----------------------------------------------------------------------------------------------------------------------
Service GetRowDelimiter(objLog)

    RowDelimiter    = ''

    If objLog NE '' then
        RowDelimiter    = Memory_Services('GetValue', objLog : '*RowDelimiter', '', '', ServiceModule)
        If RowDelimiter EQ '' then
            Error_Services('Add', 'Row delimiter not found in the ' : Service : ' service.')
        end
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = RowDelimiter

end service


//----------------------------------------------------------------------------------------------------------------------
// GetColumnDelimiter
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the delimiter to use to separate each column in the log.
//----------------------------------------------------------------------------------------------------------------------
Service GetColumnDelimiter(objLog)

    ColumnDelimiter = ''

    If objLog NE '' then
        ColumnDelimiter = Memory_Services('GetValue', objLog : '*ColumnDelimiter', '', '', ServiceModule)
        If ColumnDelimiter EQ '' then
            Error_Services('Add', 'Column delimiter not found in the ' : Service : ' service.')
        end
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = ColumnDelimiter

end service


//----------------------------------------------------------------------------------------------------------------------
// GetColumnHeaders
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the column headers that should be in the log.
//----------------------------------------------------------------------------------------------------------------------
Service GetColumnHeaders(objLog)

    ColumnHeaders   = ''

    If objLog NE '' then
        ColumnHeaders   = Memory_Services('GetValue', objLog : '*ColumnHeaders', '', '', ServiceModule)
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = ColumnHeaders

end service


//----------------------------------------------------------------------------------------------------------------------
// GetColumnWidths
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the column widths that should be used to truncate or pad each column in the log.
//----------------------------------------------------------------------------------------------------------------------
Service GetColumnWidths(objLog)

    ColumnWidths    = ''

    If objLog NE '' then
        ColumnWidths    = Memory_Services('GetValue', objLog : '*ColumnWidths', '', '', ServiceModule)
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = ColumnWidths

end service


//----------------------------------------------------------------------------------------------------------------------
// GetQuoteValues
//
// objLog   - Object handle to the log file. - [Required]
//
// Returns the flag to indicate whether column values should be quoted or not.
//----------------------------------------------------------------------------------------------------------------------
Service GetQuoteValues(objLog)

    QuoteValues = ''

    If objLog NE '' then
        QuoteValues = Memory_Services('GetValue', objLog : '*QuoteValues', '', '', ServiceModule)
        If QuoteValues NE True$ then QuoteValues = False$
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

    Response    = QuoteValues

end service


//----------------------------------------------------------------------------------------------------------------------
// CreateLogFile
//
// objLog   - Object handle to the log file. - [Required]
//
// Creates (or clears out) a log file associated with the indicated log object handle.
//----------------------------------------------------------------------------------------------------------------------
Service CreateLogFile(objLog)

    If objLog NE '' then
        LogFullPath = Logging_Services('GetLogFullPath', objLog)
        If Error_Services('NoError') then
            Status()    = 0
            OSWrite '' to LogFullPath
            Status      = Status()
            If Status GT 0 then
                Error_Services('Add', 'Unable to clear ' : LogFullPath : ' in the ' : Service : ' service.')
            end
        end
    end else
        Error_Services('Add', 'objLog argument was missing from the ' : Service : ' service.')
    end

end service


Service CleanLogFolders(NumDays)
    
    FileExclusionList   = 'Canary.txt':@VM:'Canary.vbs'
    AppRootPath         = Environment_Services('GetApplicationRootPath')
    LogPath             = AppRootPath : '\LogFiles\'
    SetInitDirOptions("D")
	InitDir LogPath:'*'
	FolderList  = DirList()
	// Remove . directory listing
    FolderList  = Delete(FolderList, 1, 0, 0)
    // Remove .. directory listing
    FolderList  = Delete(FolderList, 1, 0, 0)
    Today       = Date()
	SetInitDirOptions("")
	For each Folder in FolderList
        FolderPath = LogPath:Folder:'\'
        InitDir FolderPath:'*'
        FileList   = DirList()
        If FileList NE '' then
            For each Filename in FileList
                Locate FileName in FileExclusionList using @VM setting vPos else
                    FilePath      = FolderPath:Filename
                    FileInfo      = Dir(FilePath)
                    LastWriteDate = FileInfo<2>
                    FileAge       = Today - LastWriteDate
                    If FileAge GT NumDays then
                       OSDelete FilePath
                    end
                end
            Next Filename
        end
	Next Folder
    
end service


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

EmailMessage:

    Done            = False$
    Error           = False$
    MsgSent         = ''

    ConfigFile      = ''
    ConfigFile<1>   = SendUsing_Port$
    ConfigFile<2>   = ''
    ConfigFile<3>   = 25                        ; // Server port
    *ConfigFile<4>   = 'appmail.eu.infineon.com' ; // Mail server
    ConfigFile<4>   = 'mailrelay-external.infineon.com' ; // Mail server
    ConfigFile<5>   = True$                     ; // Authenticate
    ConfigFile<6>   = 'oinotify@infineon.com'   ; // Username
    ConfigFile<7>   = 'oinotify1'               ; // Password
    ConfigFile<8>   = False$                    ; // Use SSL

    If EmailMessage EQ '' then
        EmailMessage    = LogData : \0D0A0D0A\ : RetStack()<2>
    end else
        EmailMessage   := \0D0A0D0A\ : LogData : \0D0A0D0A\ : RetStack()<2>
    end

    SentFrom    = ''
    SentTo      = ''
    Message     = ''
    Message<1>  = 'AppendLog Message'                   ; // Subject
    Message<2>  = 'oinotify@infineon.com'               ; // From (email address)
    Message<3>  = EmailAddresses                        ; // Send to (email address)
    Message<5>  = ''                                    ; // Blind Carbon Copy (email address)
    Message<6>  = ''                                    ; // Reply To (email address)
    Message<7>  = 'TEXT'                                ; // Content Type (TEXT or HTML)
    Message<8>  = EmailMessage                          ; // Content / Body
    Message<9>  = ''                                    ; // Attachment(s) (path to file name(s))

    Result      = SRP_Send_Mail(Message, ConfigFile)

return
