import clr
clr.AddReference('Soti.IoT.SemanticEngine.Conversions')
from System.Collections.Generic import List

from Soti.IoT.SemanticEngine.Conversions.Interpreters import FirmwareInterpreter
from Soti.IoT.SemanticEngine.Conversions.Interpreters import FirmwareMetadata
import re

print("Loading ZebraRPCFirmwareInterpreter")

class ZebraRPCFirmwareInterpreter(FirmwareInterpreter):

    def GetMetadata(self, fileName, fileBytes, *args):
        #models
        models = List[str]()
        version = ""
              
        # Decode the bytearray to an ASCII string
        fileString = bytes(fileBytes).decode('ascii', errors='ignore')
        lines = fileString.splitlines()

        if len(lines) < 2 or not lines[0].strip().startswith('! PROGRAM'):
              return FirmwareMetadata(version, models)
        
        # zebra firmware is VXX.XX.XXZ on the second line
        version = lines[1].strip()

        modelIdentifier = version.split('.')[0].strip('V')

        if modelIdentifier == "68":
            models.Add('QLn220')
            models.Add('QLn310')
            models.Add('QLn320')
            models.Add('QLn420')
            models.Add('QLn220 HC')
            models.Add('QLn320 HC')
        elif modelIdentifier == "72":
            models.Add('ZT210')
            models.Add('ZT220')
            models.Add('ZT230')
        elif modelIdentifier == "73":
            models.Add('iMZ220')
            models.Add('iMZ320')
        elif modelIdentifier == "74":
            models.Add('ZD500')
            models.Add('ZD500R')
        elif modelIdentifier == "75":
            models.Add('ZT410')
            models.Add('ZT420')
        elif modelIdentifier == "76":
            models.Add('ZQ510')
            models.Add('ZQ520')
        elif modelIdentifier == "78":
            models.Add('ZR338')
        elif modelIdentifier == "79":
            models.Add('ZR628')
            models.Add('ZR638')
        elif modelIdentifier == "80": # Listed below as 96, for these three models FW is V80 priority to Link-OS 6.8 release 2
            models.Add('ZT510')
            models.Add('ZT610')
            models.Add('ZT620')
        elif modelIdentifier == "81":
            models.Add('ZQ310')
            models.Add('ZQ320')
        elif modelIdentifier == "82":
            models.Add('ZR318')
            models.Add('ZR328')
        elif modelIdentifier == "83":
            models.Add('ZD510')
            models.Add('ZD510-HC')
        elif modelIdentifier == "84":
            models.Add('ZD410d')
            models.Add('ZD420c')
            models.Add('ZD420d')
            models.Add('ZD420t')
            models.Add('ZD620d')
            models.Add('ZD620t')
        elif modelIdentifier == "85":
            models.Add('ZQ610')
            models.Add('ZQ620')
            models.Add('ZQ630')
            models.Add('ZQ630R')
        elif modelIdentifier == "86":
            models.Add('ZR658')
            models.Add('ZR668')
        elif modelIdentifier == "89":
            models.Add('ZD220')
            models.Add('ZD230')
            models.Add('ZD888')
        elif modelIdentifier == "91":
            models.Add('ZQ511')
            models.Add('ZQ511R')
            models.Add('ZQ521')
            models.Add('ZQ521R')
        elif modelIdentifier == "92":
            models.Add('ZT411')
            models.Add('ZT421')
        elif modelIdentifier == "93":
            models.Add('ZD411')
            models.Add('ZD421')
            models.Add('ZD421c')
            models.Add('ZD421d')
            models.Add('ZD421t')
            models.Add('ZD611')
            models.Add('ZD621')
            models.Add('ZD621d')
            models.Add('ZD621t')
        elif modelIdentifier == "94":
            models.Add('ZE511')
            models.Add('ZE511 RH')
            models.Add('ZE521')
            models.Add('ZE521 RH')
        elif modelIdentifier == "96":
            models.Add('ZT510')
            models.Add('ZT610')
            models.Add('ZT620')
        elif modelIdentifier == "97":
            models.Add('ZT111')
            models.Add('ZT211')
            models.Add('ZT231')
        elif modelIdentifier == "100":
            models.Add('ZQ610 Plus')
            models.Add('ZQ620 Plus')
            models.Add('ZQ630 Plus')
            models.Add('ZQ630R Plus')
        elif modelIdentifier == "101":
            models.Add('ZQ310 Plus')
            models.Add('ZQ320 Plus')
             
        return FirmwareMetadata(version, models)

        
    def ValidateVersion(self, rawVersion, *args):

        # rawVersion is the version parsed from the method above (GetMetaData)
        # we validate the version here to make sure it's in the correct format
        # which in this case for zebra is Vxx.xx.xxZ
        if not rawVersion[0] == "V" or not rawVersion[len(rawVersion) - 1] == "Z":
            return False
        
        content = rawVersion[1:-1] # remove first and last char
        parts = content.split(".") # split by . 

        # check to make sure everything is a digit
        for part in parts:
            if not part.isdigit():
                return False

        return True


    
    ##version 1 is device state property
    ##version 2 is firmware file version
    def CompareVersions(self, deviceStateVersionRaw, firmwareFileVersionRaw):
        
        # remove V and Z
        deviceStateVersionContent = deviceStateVersionRaw[1:-1]
        firmwareVersionContent = firmwareFileVersionRaw[1:-1]
        
        deviceStateVersion = int(deviceStateVersionContent.replace('.', ''))
        firmwareFileVersion = int(firmwareVersionContent.replace('.', ''))

        if deviceStateVersion > firmwareFileVersion:
            return 1
        elif firmwareFileVersion > deviceStateVersion:
            return -1
        else:
            return 0

plugin = ZebraRPCFirmwareInterpreter("ZebraRPCFirmwareInterpreter")

store.Add(plugin)