Imports System.IO
Imports UTS_Core.DebugLog
Imports UTS_Core.Security

Namespace UTSModule.License

    Public Class License
        ''' <summary> License文件字段枚举 </summary>
        Private Enum LicenseKeyEnum
            ''' <summary>客户名</summary>
            VendorName

            ''' <summary>注册日期</summary>
            AuthorizationDate

            ''' <summary>截止日期</summary>
            ExpirationDate

            ''' <summary>管理员账号</summary>
            DefaultUser

            ''' <summary>管理员密码</summary>
            DefaultPassword

            ''' <summary>远程数据库URL或IP</summary>
            MysqlServer

            ''' <summary>远程数据库连接端口</summary>
            MysqlPort

            ''' <summary>远程数据库账号</summary>
            MysqlUserID

            ''' <summary>远程数据库密码</summary>
            MysqlPassword

            ''' <summary>远程数据库私有操作库</summary>
            MysqlDatabase

            ''' <summary>远程数据库共有操作库</summary>
            PublicDb

            ''' <summary>本地数据库存放文件夹</summary>
            SqliteDir

            ''' <summary>本地数据库文件名</summary>
            SqliteName

            ''' <summary>本地数据库密码</summary>
            SqlitePassword


            ''' <summary>客户MAC地址,锁定|MAC时使用</summary>
            MAC

            ''' <summary>备注</summary>
            Remark

            ''' <summary>UTS版本号</summary>
            UtsVersion

            ''' <summary>签名</summary>
            Signature
        End Enum

        ''' <summary> License文件校验返回枚举值</summary>
        Public Enum LicenseCheckCodeEnum

            ''' <summary>未找到License</summary>
            NoLicense

            ''' <summary>无法打开License</summary>
            CantOpenLicense

            ''' <summary>无效的License</summary>
            InvalidLicense

            ''' <summary>校验通过</summary>
            CheckPass
        End Enum


        ''' <summary>License校验结果</summary>
        Public Enum EnLicenseCheckCode
            ''' <summary>校验通过</summary>
            CheckPass

            ''' <summary>无效的客户</summary>
            InvalidCustomer

            ''' <summary>无效的注册日期</summary>
            InvalidAuthorizationDate

            ''' <summary>无效的截止日期</summary>
            InvalidExpirationDate

            ''' <summary>无效的用户</summary>
            InvalidDefaultUser

            ''' <summary>无效的用户密码</summary>
            InvalidDefaultPassword

            ''' <summary>无效的MAC地址</summary>
            InvalidMac

            ''' <summary>无效的UTS版本</summary>
            InvalidUtsVersion

            ''' <summary>无效的签名</summary>
            InvalidSignature

            ''' <summary>无效的数据库地址</summary>
            InvalidDatabaseServer

            ''' <summary>无效的数据库名</summary>
            InvalidDatabaseName

            ''' <summary>无效的数据库用户</summary>
            InvalidDatabaseUserID

            ''' <summary>无效的数据库密码</summary>
            InvalidDatabaseUserPassword

            ''' <summary>无效的数据库端口号</summary>
            InvalidDatabaseUserPort

            ''' <summary>无效的数据库名(sqlite)</summary>
            InvalidDatabaseFileName

            ''' <summary>无效的数据库文件夹名(sqlite)</summary>
            InvalidDatabaseDirName
        End Enum


        ''' <summary>存储License签名校验值</summary>
        Private ReadOnly _standardSignature As String = "this is a valid license data"

        ''' <summary>License密钥</summary>
        Private ReadOnly _licenseAesKey As String = "8h(*H&-987OygO8yg*yS$&G&aG9*&6g96*&7^RA65s76r*&&G(*(7(Gyg7#7Ff7F*&(*&&^5GHo96tr5ff&*Hphg7665^fyu&uOhj0j[0[(jOIhI&g77FgghO*hhHY"

        Sub New(licensePath As String)
            ReadLicenseFile(licensePath)
        End Sub


        ''' <summary>
        ''' 获取客户名
        ''' </summary>
        ''' <returns>客户名</returns>
        Public Property VendorName As String

        ''' <summary>
        ''' 获取注册日期
        ''' </summary>
        ''' <returns>注册日期</returns>
        Public Property AuthorizationDate() As String

        ''' <summary>
        ''' 获取截止日期
        ''' </summary>
        ''' <returns>截止日期</returns>
        Public Property ExpirationDate() As String

        ''' <summary>
        ''' 获取管理员账号
        ''' </summary>
        ''' <returns>管理员账号</returns>
        Public Property DefaultUser() As String

        ''' <summary>
        ''' 获取管理员密码
        ''' </summary>
        ''' <returns>管理员密码</returns>
        Public Property DefaultPassword() As String

        ''' <summary>
        ''' 远程数据库URL或IP
        ''' </summary>
        ''' <returns>远程数据库URL或IP</returns>
        Public Property MysqlServer() As String

        ''' <summary>
        ''' 远程数据库连接端口
        ''' </summary>
        ''' <returns>远程数据库连接端口</returns>
        Public Property MysqlPort() As String

        ''' <summary>
        ''' 远程数据库账号
        ''' </summary>
        ''' <returns>远程数据库账号</returns>
        Public Property MysqlUserID() As String


        ''' <summary>
        ''' 远程数据库密码
        ''' </summary>
        ''' <returns>远程数据库密码</returns>
        Public Property MysqlPassword() As String

        ''' <summary>
        ''' 远程数据库操作库
        ''' </summary>
        ''' <returns>远程数据库操作库</returns>
        Public Property MysqlDatabase() As String


        ''' <summary>
        ''' 远程数据库公开库
        ''' </summary>
        ''' <returns></returns>
        Public Property PublicDb() As String


        ''' <summary>
        ''' 本地数据库存放文件夹
        ''' </summary>
        ''' <returns>本地数据库存放文件夹</returns>
        Public Property SqliteDir() As String

        ''' <summary>
        ''' 本地数据库文件名
        ''' </summary>
        ''' <returns>本地数据库文件名</returns>
        Public Property SqliteName() As String

        ''' <summary>
        ''' 本地数据库密码
        ''' </summary>
        ''' <returns>本地数据库密码</returns>
        Public Property SqlitePassword() As String

        ''' <summary>
        ''' 获取客户MAC地址
        ''' </summary>
        ''' <returns>客户MAC地址</returns>
        Public Property Mac() As String

        ''' <summary>
        ''' 获取备注
        ''' </summary>
        ''' <returns>备注</returns>
        Public Property Remark() As String


        ''' <summary>
        ''' 获取UTS版本号
        ''' </summary>
        ''' <returns>UTS版本号</returns>
        Public Property UtsVersion() As String

        ''' <summary>
        ''' 获取签名
        ''' </summary>
        ''' <returns>签名</returns>
        Public Property Signature() As String


        Public Function DealLicenseString(strLicense As String) As Boolean
            strLicense = strLicense.Replace(vbLf, String.Empty)

            Dim lines() As String = strLicense.Split(Chr(13))
            For Each line As String In lines
                Dim keyValues As String() = line.Split("="c)
                If keyValues.Length = 2 Then
                    keyValues(0) = keyValues(0).Trim()
                    keyValues(1) = keyValues(1).Trim()
                    InitLicenseField(keyValues(0), keyValues(1))
                Else
                    Throw New Exception($"ReadLicense Error:{LicenseCheckCodeEnum.InvalidLicense}")
                End If
            Next
            Return True
        End Function

        Private Sub InitLicenseField(key As String, value As String)
            Dim field As LicenseKeyEnum
            If [Enum].TryParse(key, field) = False Then
                ApplicationLog.WriteLog(ApplicationLog.LogTypes.Error, $"Error LicenseField,Key:{key},Value:{value}")
                Return
            End If

            Select Case field
                Case LicenseKeyEnum.AuthorizationDate
                    AuthorizationDate = value
                Case LicenseKeyEnum.DefaultPassword
                    DefaultPassword = value
                Case LicenseKeyEnum.DefaultUser
                    DefaultUser = value
                Case LicenseKeyEnum.ExpirationDate
                    ExpirationDate = value
                Case LicenseKeyEnum.MAC
                    Mac = value
                Case LicenseKeyEnum.Remark
                    Remark = value
                Case LicenseKeyEnum.Signature
                    Signature = value
                Case LicenseKeyEnum.UtsVersion
                    UtsVersion = value
                Case LicenseKeyEnum.VendorName
                    VendorName = value
                Case LicenseKeyEnum.MysqlServer
                    MysqlServer = value
                Case LicenseKeyEnum.MysqlPort
                    MysqlPort = value
                Case LicenseKeyEnum.MysqlUserID
                    MysqlUserID = value
                Case LicenseKeyEnum.MysqlPassword
                    MysqlPassword = value
                Case LicenseKeyEnum.MysqlDatabase
                    MysqlDatabase = value
                Case LicenseKeyEnum.PublicDb
                    PublicDb = value
                Case LicenseKeyEnum.SqliteDir
                    SqliteDir = value
                Case LicenseKeyEnum.SqliteName
                    SqliteName = value
                Case LicenseKeyEnum.SqlitePassword
                    SqlitePassword = value
                Case Else
                    ApplicationLog.WriteLog(ApplicationLog.LogTypes.Warn, $"Untreated,Key:{key},Value:{value}")
            End Select
        End Sub


        ''' <summary>
        ''' 读取License文件所有内容，并进行解密,将解密后的内容存入License字典中
        ''' </summary>
        ''' <param name="licensePath">License文件完整路径(含文件名)</param>
        Public Sub ReadLicenseFile(licensePath As String)
            If File.Exists(licensePath) = False Then
                Throw New Exception($"ReadLicense Error:{LicenseCheckCodeEnum.NoLicense}")
            End If

            Dim strLicense As String = Aes128.DecryptStr(File.ReadAllText(licensePath), _licenseAesKey)
            DealLicenseString(strLicense)
        End Sub


        Public Function CheckLicense() As Boolean
            '校验注册日期
            Dim nowDate As String = Format(Now.Date, "yyyy-MM-dd") & " " & Format(TimeOfDay, "HH:mm:ss")
            If String.Compare(nowDate, AuthorizationDate, StringComparison.OrdinalIgnoreCase) < 0 Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidAuthorizationDate}")
            End If

            '校验截止日期
            If String.Compare(nowDate, ExpirationDate, StringComparison.OrdinalIgnoreCase) > 0 Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidExpirationDate}")
            End If

            '默认用户
            If String.IsNullOrWhiteSpace(DefaultUser) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDefaultUser}")
            End If

            '默认用户密码
            If String.IsNullOrWhiteSpace(DefaultPassword) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDefaultPassword}")
            End If




            '校验签名
            If String.Compare(Signature, _standardSignature, True) <> 0 Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidSignature}")
            End If




            '校验数据库URL或IP
            If String.IsNullOrEmpty(MysqlServer) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseServer}")
            End If

            If String.IsNullOrEmpty(MysqlDatabase) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseName}")
            End If

            If String.IsNullOrEmpty(MysqlPort) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseUserPort}")
            End If

            If String.IsNullOrEmpty(MysqlUserID) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseUserID}")
            End If


            If String.IsNullOrEmpty(MysqlPassword) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseUserPassword}")
            End If

            If String.IsNullOrEmpty(SqliteDir) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseDirName}")
            End If

            If String.IsNullOrEmpty(SqliteName) Then
                Throw New Exception($"CheckLicense Error:{EnLicenseCheckCode.InvalidDatabaseFileName}")
            End If

            Return True
        End Function
    End Class
End Namespace