
import shutil,zipfile
from gimphelpers import *

# Classes to handle the places where we keep the addOns
class ResourceContainer(object):
    """ Describes a path object that contains resources """
    def __init__(self, storedContainerPath, activeResourcesDir):
        self.storedContainerPath = storedContainerPath
        self.activeResourcesDir = activeResourcesDir

    def containerName(self):
        return os.path.splitext(os.path.basename(self.storedContainerPath))[0]

    def activeContainerPath(self):
        return os.path.join(self.activeResourcesDir, self.containerName())

    def isActive(self):
        return os.path.isdir(self.activeContainerPath())

    def activate(self):
        """Implemented by derived classes"""
        pass

    def deactivate(self):
        """General case handled here, symlink handled by overriding method"""
        activePath = self.activeContainerPath()
        trace(f'Removing {activePath}')
        try:
            shutil.rmtree(activePath, ignore_errors=True)
        except Exception as e:
            trace(f'Cannot remove {activePath}: {e}')

class LinkedDirectory(ResourceContainer):
    """Class to handle a directory that is linked """

    def __init__(self, containerPath, activeResourcesDir):
        super(LinkedDirectory, self).__init__(containerPath, activeResourcesDir)

    def activate(self):
        activePath=self.activeContainerPath()
        trace(f'Activating linked directory from {self.storedContainerPath} to {activePath}')
        try:
            os.symlink(self.storedContainerPath, activePath)
        except Exception as e:
            trace(f'Cannot create link {activePath}: {e}')

    def deactivate(self):
        activePath=self.activeContainerPath()
        trace(f'Unlinking {activePath}')
        try:
            os.unlink(activePath)
        except Exception as e:
            trace(f'Cannot remove link {activePath}: {e}')

class CopiedDirectory(ResourceContainer):
    """Class to handle a directory that is copied"""

    def __init__(self, containerPath, activeResourcesDir):
        super(CopiedDirectory, self).__init__(containerPath, activeResourcesDir)

    def activate(self):
        activePath = self.activeContainerPath()
        trace(f'Activating copied directory from {self.storedContainerPath} to {activePath}')
        try:
            shutil.copytree(self.storedContainerPath, activePath)
        except Exception as e:
            trace(f'Cannot copy directory to {activePath}: {e}')

class ZipFile(ResourceContainer):
    """Class to handle a zip file """

    def __init__(self, containerPath, activeResourcesDir):
        super(ZipFile, self).__init__(containerPath, activeResourcesDir)
        self.zipFile = zipfile.ZipFile(containerPath)

    def activate(self):
        zipFile = zipfile.ZipFile(self.storedContainerPath)
        activePath = self.activeContainerPath()
        trace(f'Activating ZIP file from {self.storedContainerPath} to {activePath}')
        try:
            zipFile.extractall(activePath)
        except Exception as e:
            trace(f'Cannot unzip to {activePath}: {e}')
        finally:
            zipFile.close()
