"""
Name: xferFileHandler
Title: 
Author: Cooper
Date: 14/02/2019

Desc:  This script deals with the payload received over 3rd party FTP servers and not WDM.
This will unzip and move files as necessary

"""
import os
import gzip
import zipfile
import shutil

class XferFileHandler(object):
    def __init__(self, confDir, dataDir):
        self.tempPath = r"/tmp"

        self.confDir = confDir
        self.dataDir = dataDir

        self.newEric = False
        self.newConf = False
        self.newSerial = False
        self.newFont = False
        self.update_error = False

    def unzipPayload(self, filename):
        """
        Unzips the payload
        """
        zipPath = os.path.join(self.tempPath, filename)

        try:
            xferZip  = zipfile.ZipFile(zipPath, "r")
        except FileNotFoundError as err:
            print("XFH Cannot open: %s" % err)
            self.update_error = True
            return 1

        try:
            xferZip.extractall(self.tempPath)
            xferZip.close()
        except zipfile.BadZipFile as err:
            print("XFH Cannot extract: %s" % err)
            self.update_error = True
            return 1

        print("XFH Files extracted")
        return 0

    """
    ###################################################################################################################
    File discovery
    """
    def discoverFiles(self):
        """
        Looks for files that were previously extracted, the case of the original file is taken into account and everything
        is reduced to lower case when moved.
        """
        xferFiles = os.listdir(self.tempPath)
        print(xferFiles)

        for xferFile in xferFiles:
            if xferFile.lower() == "eric.bin":
                print("XFH Found eric.bin")
                # We should purge any existing database (bin) in the payload dir
                try:
                    for file in os.listdir(os.path.join(self.dataDir, "payload")):
                        if not file.lower == "eric.json":
                            os.remove(os.path.join(self.dataDir, "payload", file))
                except OSError:
                    print("XFH Cannot remove payload file(s)")

                status = self.moveFile(xferFile, os.path.join(self.dataDir, "payload"), True)

                if not status:
                    self.newEric = True

            elif xferFile.lower() == "config.cfg":
                print("XFH Found config.cfg")
                status = self.moveFile(xferFile, self.confDir, True)

                try:
                    os.remove(os.path.join(self.confDir, "network.done"))
                except OSError:
                    print("XFH Cannot remove network flag")

                if not status:
                    self.newConf = True

            elif xferFile.lower() == "serialdata.json":
                print("XFH Found serialdata.cfg")
                status = self.moveFile(xferFile, self.confDir, True)
                if not status:
                    self.newSerial = True

            elif xferFile.lower() == "fontlib.bin":
                print("XFH Found fontlib.bin")
                status = self.moveFile(xferFile, os.path.join(self.dataDir, "renderbox"), True)
                if not status:
                    self.newFont = True

    """
    ###################################################################################################################
    File moving and flag functions
    """

    def createFlag(self, path):
        path = os.path.join(path, "dirty.biz")
        try:
            file = open(path, "w")
            file.close()
            print("XFH Flag created: %s" % path)
            return 0
        except IOError:
            print("XFH Cannot create flag")
            return 1

    def removeFlag(self, path):
        path = os.path.join(path, "dirty.biz")
        try:
            os.remove(path)
            print("XFH Flag removed: %s" % path)
            return 0
        except IOError:
            print("XFH Cannot remove flag")
            return 1

    def checkFlag(self, path):
        if "dirty.biz" in os.listdir(path):
            return True
        else:
            return False

    def moveFile(self, fileName, destPath, changeCase):
        try:
            srcPath = os.path.join(self.tempPath, fileName)
            if changeCase:
                dstPath = os.path.join(destPath, fileName.lower() + ".tmp")
            else:
                dstPath = os.path.join(destPath, fileName + ".tmp")

            if self.createFlag(destPath):
                self.update_error = True
                return 1
            shutil.move(srcPath, dstPath)
        except OSError as e:
            print("XFH Cannot move: %s", e)
            self.update_error = True
            return 1
        else:
            print("\tXFH Moved! %s" % dstPath)
            if self.removeFlag(destPath):
                return 1
            if not self.renameFile(fileName, destPath, changeCase):
                return 0
            else:
                self.update_error = True
                return 1

    def renameFile(self, fileName, destPath, changeCase):
        flagstatus = self.checkFlag(destPath)

        if not flagstatus:
            try:
                if changeCase:
                    fileName = fileName.lower()
                srcPath = os.path.join(destPath, fileName + ".tmp")
                dstPath = os.path.join(destPath, fileName.replace(".tmp", ""))
                #shutil.move replaces existing files if there is one
                shutil.move(srcPath, dstPath)
            except OSError as e:
                print("XFH Cannot rename: %s", e)
                return 1
            else:
                print("\tXFH renamed %s > %s" % (srcPath, dstPath))
                return 0

        else:
            print("XFH Flag present, skip rename")
            return 1

if __name__ == "__main__":
    xfh = XferFileHandler(None, "../payload")
    xfh.unzipPayload()