'
'用于对字符串进行分隔后重新整形组合
'例如：Source String：12.23.456
'      OutputString：012.023.456
'
'History:
'Momo 2022-03-25 :  第一版
'
'-----------------------------------------------------
'FormatMode = 1：FormatMode_Split_Alignment_And_Regroup '按照固定字符分隔，格式化，然后重组
'           = 2：FormatMode_Split_String '分隔字符串，例如：“OK，23” 从中间提取出“OK”和“23”
'           = 3: FormatMode_Check_Each_Character '对每个字符进行格式检测 
'
'
'
'-----------------------------------------------------
'ElementConvetModeEnum = 1: ElementConvetModeEnum_FixedLenght_Front_Fill_Zero '按照固定长度，前面补零，适合于数值转换场合
'                        2：FormatMode_Split_String_GetElement_By_Idx '分隔后按指定索引获取分隔后的字符，索引从0开始，每次只返回一个结果，指定索引超过长度是无返回




Namespace UTSModule.Test.Command.ConverterCommand
    Public Class FormatStringExecutor
        Inherits TestCommandExecutor

        Private Enum ElementConvetModeEnum
            ElementConvetModeEnum_FixedLenght_Front_Fill_Zero = 1 '固定长度，不足长度加0
            FormatMode_Split_String_GetElement_By_Idx '分隔后按指定下标获取分隔后的字符，下标从0开始，每次只返回一个结果，指定下标超过长度是无返回
        End Enum

        Private Enum FormatModeEnum
            FormatMode_Split_Alignment_And_Regroup = 1 '按照固定字符分隔，格式化，然后重组
            FormatMode_Split_String '分隔字符串，例如：“OK，23” 从中间提取出“OK”和“23”
            FormatMode_Check_Each_Character
        End Enum
        Private Enum ParasEnum
            SourceString                   '源字符串
            FormatMode                     '整形模式’
            Symbol_Of_Split                 '分隔符’
            Len_Of_SplitByFixedLength      '按固定模式分隔的情况下，分隔长度依据’
            Element_Convet_Mode            '分隔后元素转换模式’
            Length_Format                  '转换后元素格式化’
            Connect_Symbol                 '连接字符’
            OutputString                   '处理后字符串’
            MAX
        End Enum
        Private ReadOnly _Para(ParasEnum.MAX) As String

        '提取参数，与数据表中描述相同
        Sub New(command As TestCommand)
            MyBase.New(command)

            Dim idx As Integer
            For idx = 0 To ParasEnum.MAX - 1
                _Para(idx) = command.Parameter(idx)
            Next
        End Sub

        '执行模块’
        Public Overrides Function Execute() As TestCommandReturn
            Dim tmpStrReslut As String = ""
            Dim tmpStrErrMsg As String = ""
            '源字符串为空则为返回错误
            If String.IsNullOrEmpty(_Para(ParasEnum.SourceString)) Then
                CommandReturn.RecordValue = "" '字符串处理后的返回值
                CommandReturn.ExecuteResultTipString = $"源字符串不能为空"                  '调试时显示在log窗口的信息’
                CommandReturn.ExecuteResult = False                                         '函数处理结果，只能是bool类型’
                Return CommandReturn
            End If

            '根据格式化模式确定格式化处理方法’
            Select Case Val(_Para(ParasEnum.FormatMode))
                 '按照固定字符分隔，格式化，然后重组
                Case FormatModeEnum.FormatMode_Split_Alignment_And_Regroup
                    Dim tmpReslut As Boolean = Run_FormatMode_Split_Alignment_And_Regroup(_Para(ParasEnum.SourceString),
                                                                                          _Para(ParasEnum.Symbol_Of_Split),
                                                                                          _Para(ParasEnum.Element_Convet_Mode),
                                                                                          _Para(ParasEnum.Length_Format),
                                                                                          _Para(ParasEnum.Connect_Symbol),
                                                                                          tmpStrReslut,
                                                                                          tmpStrErrMsg)

                    If tmpReslut = True Then
                        '执行成功
                        CommandReturn.RecordValue = tmpStrReslut
                        CommandReturn.ExecuteResultTipString = ""
                        CommandReturn.ExecuteResult = True
                    Else
                        '执行失败’
                        CommandReturn.RecordValue = "" '字符串处理后的返回值
                        CommandReturn.ExecuteResultTipString = tmpStrErrMsg                  '调试时显示在log窗口的信息’
                        CommandReturn.ExecuteResult = False
                    End If
                    Return CommandReturn

                '分隔字符串，例如：“OK，23” 从中间提取出“OK”和“23”
                Case FormatModeEnum.FormatMode_Split_String
                    Dim tmpReslut As Boolean = Run_FormatMode_Split_String(_Para(ParasEnum.SourceString),
                                                                           _Para(ParasEnum.Symbol_Of_Split),
                                                                           _Para(ParasEnum.Len_Of_SplitByFixedLength),
                                                                           _Para(ParasEnum.Element_Convet_Mode),
                                                                           tmpStrReslut,
                                                                           tmpStrErrMsg)
                    If tmpReslut = True Then
                        '执行成功
                        CommandReturn.RecordValue = tmpStrReslut
                        CommandReturn.ExecuteResultTipString = ""
                        CommandReturn.ExecuteResult = True
                    Else
                        '执行失败’
                        CommandReturn.RecordValue = "" '字符串处理后的返回值
                        CommandReturn.ExecuteResultTipString = tmpStrErrMsg                  '调试时显示在log窗口的信息’
                        CommandReturn.ExecuteResult = False
                    End If
                    Return CommandReturn

                ''对每个字符进行格式检测 
                Case FormatModeEnum.FormatMode_Check_Each_Character
                    Dim tmpReslut As Boolean = Run_FormatMode_Check_Each_Character(_Para(ParasEnum.SourceString),
                                                                           _Para(ParasEnum.Symbol_Of_Split),
                                                                           _Para(ParasEnum.Len_Of_SplitByFixedLength),
                                                                           _Para(ParasEnum.Element_Convet_Mode),
                                                                           _Para(ParasEnum.Length_Format),
                                                                           tmpStrReslut,
                                                                           tmpStrErrMsg)
                    If tmpReslut = True Then
                        '执行成功
                        CommandReturn.RecordValue = tmpStrReslut
                        CommandReturn.ExecuteResultTipString = ""
                        CommandReturn.ExecuteResult = True
                    Else
                        '执行失败’
                        CommandReturn.RecordValue = tmpStrReslut '字符串处理后的返回值
                        CommandReturn.ExecuteResultTipString = tmpStrErrMsg                  '调试时显示在log窗口的信息’
                        CommandReturn.ExecuteResult = False
                    End If
                    Return CommandReturn

                Case Else

                    CommandReturn.RecordValue = "" '字符串处理后的返回值
                    CommandReturn.ExecuteResultTipString = $"FormatMode 参数不正确"                  '调试时显示在log窗口的信息’
                    CommandReturn.ExecuteResult = False                                         '函数处理结果，只能是bool类型’
                    Return CommandReturn
            End Select

        End Function


        'Dim tmpReslut As Boolean = Run_FormatMode_Check_Each_Character(_Para(ParasEnum.SourceString),
        '                                                                   _Para(ParasEnum.Symbol_Of_Split),
        '                                                                   _Para(ParasEnum.Len_Of_SplitByFixedLength),
        '                                                                   _Para(ParasEnum.Element_Convet_Mode),
        '                                                                   _Para(ParasEnum.Length_Format),
        '                                                                   tmpStrReslut,
        '                                                                   tmpStrErrMsg)
        Function Run_FormatMode_Check_Each_Character(ByVal strSourceString As String,
                                                     ByVal strSymbol_Of_Split As String,
                                                     ByVal strLen_Of_SplitByFixedLength As String,
                                                     ByVal strElement_Convet_Mode As String,
                                                     ByVal strLength_Format As String,
                                                     ByRef strOutputString As String,
                                                     ByRef strErrMsg As String) As Boolean
            'Momo 2022-03-03 add code here !
            Dim tmpString_tobe_process As String = strSourceString '待处理字符串
            Dim tmpIs_check_string_lenght As Integer = CInt(Val(strSymbol_Of_Split)) '是否确认字符串长度
            Dim tmp_stringLen_lowlimit As Integer = CInt(Val(strLen_Of_SplitByFixedLength)) '字符串长度下限
            Dim tmp_stringLen_upperlimit As Integer = CInt(Val(strElement_Convet_Mode)) '字符串长度上限
            Dim tmp_format_check_for_each_characher As Integer = CInt(Val(strLength_Format)) '字符格式化比对模式
            Dim i As Integer = 0

            If String.IsNullOrEmpty(tmpString_tobe_process) Then
                strOutputString = "FALSE" '字符串处理后的返回值
                strErrMsg = $"空字符串"    '调试时显示在log窗口的信息’
                CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                Return False
            End If

            '判断字符串长度
            If tmpIs_check_string_lenght > 0 Then
                If tmpString_tobe_process.Length < tmp_stringLen_lowlimit OrElse
                   tmpString_tobe_process.Length > tmp_stringLen_upperlimit Then
                    strOutputString = "FALSE" '字符串处理后的返回值
                    strErrMsg = $"字符串长度不正确"    '调试时显示在log窗口的信息’
                    CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                    Return False
                End If
            End If

            '对字符逐个进行格式检查
            '对每个字符都做格式检查：
            '0：不对每个字符进行检查
            '1：每个字符都必须是数字0~9
            '2：每个字符都必须是十六进制， 即0~9， A~F， 包括空格
            '3：每个字符都必须是数字或字母， 用以排除乱码
            Select Case tmp_format_check_for_each_characher
                Case 0 '不对每个字符进行检查

                Case 1 '每个字符都必须是数字0~9
                    If IsNumeric(tmpString_tobe_process) = False Then
                        strOutputString = "FALSE" '字符串处理后的返回值
                        strErrMsg = $"字符串中包含非数字内容"    '调试时显示在log窗口的信息’
                        CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                        Return False
                    End If

                Case 2 '每个字符都必须是十六进制， 即0~9， A~F， 包括空格
                    '0~9: 48~57
                    'A~F: 65~70
                    'space:32
                    If tmpString_tobe_process.Length > 0 Then
                        For i = 1 To tmpString_tobe_process.Length
                            Dim tmpChar As Char = CChar(Mid(tmpString_tobe_process, i, 1).ToUpper)

                            If (Asc(tmpChar) >= 48 AndAlso Asc(tmpChar) <= 57) OrElse '0~9
                               (Asc(tmpChar) >= 65 AndAlso Asc(tmpChar) <= 70) OrElse 'A~F
                               (Asc(tmpChar) = 32) Then 'space
                                '合法内容
                            Else
                                strOutputString = "FALSE" '字符串处理后的返回值
                                strErrMsg = $"字符串中包含非 hex 字符"    '调试时显示在log窗口的信息’
                                CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                                Return False
                            End If
                        Next
                    End If

                Case 3 '每个字符都必须是数字或字母， 用以排除乱码
                    If tmpString_tobe_process.Length > 0 Then
                        For i = 1 To tmpString_tobe_process.Length
                            Dim tmpChar As Char = CChar(Mid(tmpString_tobe_process, i, 1))

                            If (Asc(tmpChar) >= 32 AndAlso Asc(tmpChar) <= 126) Then 'space
                                '合法内容
                            Else
                                strOutputString = "FALSE" '字符串处理后的返回值
                                strErrMsg = $"字符串中包含非文本字符"    '调试时显示在log窗口的信息’
                                CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                                Return False
                            End If
                        Next
                    End If

                Case Else '其他情况

            End Select

            strOutputString = "TRUE"
            strErrMsg = ""
            CommandReturn.ExecuteResult = True
            Return True
        End Function



        Function Run_FormatMode_Split_String(ByVal strSourceString As String,
                                             ByVal strSymbol_Of_Split As String,
                                             ByVal strReturnIdx As String,
                                             ByVal strElemnetConvetMode As String,
                                             ByRef strOutputString As String,
                                             ByRef strErrMsg As String) As Boolean

            'strSourceString As String,  ：     1 源数据串
            'strSymbol_Of_Split As String, ：   3 分隔符号
            'strReturnIdx As String, ：         4 分隔后返回元素索引
            'strElemnetConvetMode As String, ： 5 执行模式

            Dim tmpStrElements() As String
            Dim tmpProcessedElements() As String
            Dim idx As Integer = CInt(Val(strReturnIdx))

            Try
                'Step1：按字符对字符串进行分隔
                tmpStrElements = Split(strSourceString, strSymbol_Of_Split)
                ReDim tmpProcessedElements(tmpStrElements.Count)

                'Step2：对每个字符串进行格式化处理
                Select Case Val(strElemnetConvetMode)
                    Case ElementConvetModeEnum.FormatMode_Split_String_GetElement_By_Idx    '分隔后按指定下标获取分隔后的字符，下标从0开始，每次只返回一个结果，指定下标超过长度是无返回
                        If idx < tmpStrElements.Count Then
                            '指定索引小于分隔后索引  
                            Dim tmpStr As String = Trim(tmpStrElements(idx))
                            strOutputString = tmpStr '字符串处理后的返回值
                            strErrMsg = ""    '调试时显示在log窗口的信息’
                        End If

                    Case Else
                        strOutputString = "" '字符串处理后的返回值
                        strErrMsg = $"Element_Convet_Mode 参数不正确"    '调试时显示在log窗口的信息’
                        CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                        Return False
                End Select

                'Step3：完成
                strErrMsg = ""
                Return True

            Catch ex As Exception
                strOutputString = "" '字符串处理后的返回值
                strErrMsg = ex.Message.ToString     '调试时显示在log窗口的信息’
                Return False
            End Try

        End Function
        Function Run_FormatMode_Split_Alignment_And_Regroup(ByVal strSourceString As String,
                                                            ByVal strSymbol_Of_Split As String,
                                                            ByVal strElement_Convet_Mode As String,
                                                            ByVal strLength_Format As String,
                                                            ByVal strConnect_Symbol As String,
                                                            ByRef strOutputString As String,
                                                            ByRef strErrMsg As String) As Boolean

            Dim tmpStrElements() As String
            Dim tmpProcessedElements() As String
            Dim idx As Integer

            Try
                'Step1：按字符对字符串进行分隔
                tmpStrElements = Split(strSourceString, strSymbol_Of_Split)
                ReDim tmpProcessedElements(tmpStrElements.Count)

                'Step2：对每个字符串进行格式化处理
                For idx = 0 To tmpStrElements.Count - 1
                    'Select Case Val(_Para(ParasEnum.Element_Convet_Mode))
                    Select Case Val(strElement_Convet_Mode) 'Momo 2023-02-25 修正数据引用---未验证
                        Case ElementConvetModeEnum.ElementConvetModeEnum_FixedLenght_Front_Fill_Zero    '固定长度，不足长度加0
                            tmpProcessedElements(idx) = Format(Val(tmpStrElements(idx)), "000").ToString

                        Case Else
                            strOutputString = "" '字符串处理后的返回值
                            strErrMsg = $"Element_Convet_Mode 参数不正确"    '调试时显示在log窗口的信息’
                            CommandReturn.ExecuteResult = False              '函数处理结果，只能是bool类型’
                            Return False
                    End Select
                Next idx

                'Step3：重组字符串
                strOutputString = ""
                For idx = 0 To tmpStrElements.Count - 1
                    strOutputString = strOutputString & tmpProcessedElements(idx)
                    If idx < tmpStrElements.Count - 1 Then strOutputString = strOutputString & strConnect_Symbol
                Next idx


                'Step4：完成
                strErrMsg = ""
                Return True

            Catch ex As Exception
                strOutputString = "" '字符串处理后的返回值
                strErrMsg = ex.Message.ToString     '调试时显示在log窗口的信息’
                Return False
            End Try

        End Function

        'SourceString                   '源字符串
        '   FormatMode                     '整形模式’
        '   Symbol_Of_Split                 '分隔符’
        '   Len_Of_SplitByFixedLength      '按固定模式分隔的情况下，分隔长度依据’
        '   Element_Convet_Mode            '分隔后元素转换模式’
        '   Length_Format                  '转换后元素格式化’
        '   Connect_Symbol                 '连接字符’
        '   OutputString                   '处理后字符串’

    End Class
End Namespace

