import logHelpers, utils,setup,os,traceback
import zipfile
import io
import azorultHelpers

tmp_i = 0

class Log:
    def __init__(self, filePath):
        self.fileHandle = open(filePath, "r", errors='ignore')

    def close(self):
        self.fileHandle.close()

######################################################

class WalletProtectionMiniFilterLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.walletAccessInfoList = []
        self.parse()

        self.cntWalletAccesses = len(self.walletAccessInfoList)
        self.isAccessingWallet = False
        if 0 < self.cntWalletAccesses:
            self.isAccessingWallet = True

        super().close()

    def parse(self):

        walletAccessInfo = []
        for line in self.fileHandle.readlines():
            if line.find("Wallet Path:") != -1:
                walletAccessInfo.append(logHelpers.extractWalletPath(line))
            if line.find("processId:") != -1:
                walletAccessInfo.append(logHelpers.extractPid(line))
            if line.find("imageName:") != -1:
                walletAccessInfo.append(logHelpers.extractImageName(line))
            if logHelpers.isAccessApproved(line):
                walletAccessInfo.append("approved")
                self.walletAccessInfoList.append(walletAccessInfo)
                walletAccessInfo = []  # empty
            if logHelpers.isAccessDenied(line):
                walletAccessInfo.append("denied")
                self.walletAccessInfoList.append(walletAccessInfo)
                walletAccessInfo = []  # empty

    def print(self):
        print("---> WalletProtectionMiniFilterLog")
        print("----> cntWalletAccesses: " + str(self.cntWalletAccesses))
        print("----> isAccessingWallet: " + str(self.isAccessingWallet))

class ClipboardHijackingProtectionMainThreadLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.detectedClipboardHijacker = False
        self.clipboardHijackerPid = 0
        self.clipboardHijackerProcessPath = ""
        self.detectedHijackerAddresses = []
        self.cntOpenClipboardFailures = 0

        self.parse()

        super().close()

    def parse(self):
        getDetectedAddresses = False
        for line in self.fileHandle.readlines():
            if line.find("OpenClipboard failed") != -1:
                self.cntOpenClipboardFailures += 1

            if logHelpers.isHijackerDetected(line):
                self.detectedClipboardHijacker = True
                self.clipboardHijackerPid = logHelpers.extractHijackerPid(line)

            if line.find("ProcessImagePath:") != -1:
                self.clipboardHijackerProcessPath = logHelpers.extractHijackerProcessPath(line)

            if line.find("detected addresses:") != -1:
                getDetectedAddresses = True
                continue #next iteration

            if getDetectedAddresses and line == '\n':
                getDetectedAddresses = False #stop, found empty line

            if getDetectedAddresses: # all lines after
                self.detectedHijackerAddresses.append(line[:-1]) #cut out newline

    def print(self):
        print("---> ClipboardHijackingProtectionMainThreadLog")
        print("----> detectedClipboardHijacker: " + str(self.detectedClipboardHijacker))
        print("----> clipboardHijackerPid: " + str(self.clipboardHijackerPid))
        print("----> detectedHijackerAddresses: " + str(self.detectedHijackerAddresses))


class ClipboardHijackingProtectionPollThreadLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.parse()
        super().close()

    def parse(self):
        for line in self.fileHandle.readlines():
            pass

    def print(self):
        print("---> ClipboardHijackingProtectionPollThreadLog")

class ClipboardMonitorLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.parse()
        super().close()

    def parse(self):
        for line in self.fileHandle.readlines():
            pass

    def print(self):
        print("---> ClipboardMonitorLog")

class FilesystemMonLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        #attributes
        self.createdProcessTuples = []

        self.crashLines = []
        self.walletsIrpOpenLines = []
        self.walletsIrpReadLines = []
        self.walletsIrpWriteLines = []

        self.parse()

        self.cntCrashLines = len(self.crashLines)
        self.cntWalletsIrpOpenLines = len(self.walletsIrpOpenLines)
        self.cntWalletsIrpReadLines = len(self.walletsIrpReadLines)
        self.cntWalletsIrpWriteLines = len(self.walletsIrpWriteLines)

        super().close()

    def parse(self):
        foundInitialProcess = False
        for line in self.fileHandle.readlines():

            if not foundInitialProcess:
                if logHelpers.isInitialSampleProcessCreated(line):
                    self.initialProcess = utils.extractStringBetween(line, "CREATE PROCESS: procId: ", " | procImagePath:")
                    foundInitialProcess = True

            if foundInitialProcess: # put everything else in this if block
                if logHelpers.isProcessCreate(line):
                    pid = logHelpers.extractPid(line)
                    processPath = logHelpers.extractProcessPath(line)
                    self.createdProcessTuples.append((pid, processPath))

                if logHelpers.isCrash(line):
                    self.crashLines.append(line)

                if logHelpers.isIrpFileOpen(line):
                    filepath = logHelpers.extractFilePath(line)
                    if utils.stringIsInList(filepath, setup.walletpaths):
                        self.walletsIrpOpenLines.append(line)

                if logHelpers.isIrpFileRead(line):
                    filepath = logHelpers.extractFilePath(line)
                    if utils.stringIsInList(filepath, setup.walletpaths):
                        self.walletsIrpReadLines.append(line)

                if logHelpers.isIrpFileWrite(line):
                    filepath = logHelpers.extractFilePath(line)
                    if utils.stringIsInList(filepath, setup.walletpaths):
                        self.walletsIrpWriteLines.append(line)

    def print(self):
        print("---> FilesystemMonLog")
        print("----> cntCrashLines: " + str(self.cntCrashLines))
        print("----> cntWalletsIrpOpenLines: " + str(self.cntWalletsIrpOpenLines))
        print("----> cntWalletsIrpReadLines: " + str(self.cntWalletsIrpReadLines))
        print("----> cntWalletsIrpWriteLines: " + str(self.cntWalletsIrpWriteLines))

class SimulationLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.parse()
        super().close()

    def parse(self):
        for line in self.fileHandle.readlines():
            pass

    def print(self):
        print("---> SimulationLog")

class HttpTrafficLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.cntHttpRequests = 0
        self.cntHttpResponses = 0
        self.cntPostRequests = 0
        self.cntGetRequests = 0
        self.cntBigRequests = 0

        self.parse()

        self.hasWalletBytesInHttpRequest = self.foundWalletBytesInHttpRequest(filePath)

        self.hasHttpResponses = False
        if self.cntHttpResponses > 0:
            self.hasHttpResponses = True

        self.hasPostRequests = False
        if self.cntPostRequests > 0:
            self.hasPostRequests = True

        self.hasGetRequests = False
        if self.cntGetRequests > 0:
            self.hasGetRequests = True

        self.hasBigRequests = False
        if self.cntBigRequests > 0:
            self.hasBigRequests = True

        super().close()

    def parse(self):
        isInRequest = False
        for line in self.fileHandle.readlines():

            if line.find("HTTP Request") != -1:
                self.cntHttpRequests += 1
                isInRequest = True

            if line.find("HTTP Response") != -1:
                self.cntHttpResponses += 1
                isInRequest = False

            if isInRequest:
                if line.find("Method: POST") != -1:
                    self.cntPostRequests += 1

                if line.find("Method: GET") != -1:
                    self.cntGetRequests += 1

                if line.find("content-length") != -1 or line.find("Content-Length") != -1:
                    contentLength = logHelpers.extractContentLength(line)
                    if contentLength > (5 * 1024):
                        self.cntBigRequests = contentLength

    def foundWalletBytesInHttpRequest(self, httpLogFilePath):
        bytePatternList = setup.walletBytePatternList
        httpDir = os.path.dirname(httpLogFilePath) + "/http/"
        try:
            requestBodiesFilenames = []
            for name in os.listdir(httpDir):
                if name.find("RequestBody") != -1:
                    requestBodiesFilenames.append(name)

            for filename in requestBodiesFilenames:
                f = open(httpDir + filename, 'rb')
                rawContent = f.read()

                if httpLogFilePath.find(setup.AZORULT32_DIRNAME) != -1:
                    keyBytes = bytes([0x0D, 0x0A, 0xC8])
                    possibleZipBytes = azorultHelpers.extractAzorultZipBytes(rawContent,keyBytes)
                    if possibleZipBytes != "":
                        rawContent = possibleZipBytes

                if httpLogFilePath.find(setup.AZORULT30_DIRNAME) != -1:
                    keyBytes = bytes([0xFE,0x29,0x36])
                    possibleZipBytes = azorultHelpers.extractAzorultZipBytes(rawContent,keyBytes)
                    if possibleZipBytes != "":
                        rawContent = possibleZipBytes

                if (rawContent.find(b"\x50\x4B\x05\x06") != -1): #check if it contains a zipfile
                    zip = zipfile.ZipFile(io.BytesIO(rawContent))

                    #foofile = zip.filelist
                    for filename in zip.namelist():  # iterate through all files in the zipfile
                        #print(filename)
                        fileBytes = zip.read(filename)
                        # scan for walletbytes inside zip
                        for bytePattern in bytePatternList:
                            if fileBytes.find(bytePattern) != -1:
                                return True

                #scan for walletbytes on plainbytes
                for bytePattern in bytePatternList:
                    if rawContent.find(bytePattern) != -1:
                        global tmp_i
                        tmp_i = tmp_i + 1
                        #print(tmp_i)
                        return True
        except Exception as e:
            print("IGNORE: " + traceback.format_exc())

        return False

    def print(self):
        print("---> HttpTrafficLog")
        print("----> cntHttpRequests: " + str(self.cntHttpRequests))
        print("----> cntHttpResponses: " + str(self.cntHttpResponses))
        print("----> cntPostRequests: " + str(self.cntPostRequests))
        print("----> cntGetRequests: " + str(self.cntGetRequests))
        print("----> cntBigRequests: " + str(self.cntBigRequests))

class WindowInteractionLog(Log):
    def __init__(self, filePath):
        super().__init__(filePath)

        self.parse()
        super().close()

    def parse(self):
        for line in self.fileHandle.readlines():
            pass

    def print(self):
        print("---> WindowInteractionLog")