import os
import tarfile as tarfile
import tempfile

from cfg_checker.common import logger_cli
from cfg_checker.common.exception import ConfigException


class TGZFile(object):
    basefile = None
    _labelname = "labelfile"

    def __init__(self, _filepath, label=None):
        # Check if this filename exists
        if not os.path.exists(_filepath):
            # If the archive not exists, create it
            # simple labelfile for a non-empty archive

            if not label:
                label = "MCP Checker TGZ file"

            with tempfile.TemporaryFile() as _tempfile:
                _tempfile.write(label.encode('utf-8'))
                _tempfile.flush()
                _tempfile.seek(0)
                # create tgz
                with tarfile.open(_filepath, "w:gz") as tgz:
                    _info = tgz.gettarinfo(
                        arcname=self._labelname,
                        fileobj=_tempfile
                    )
                    tgz.addfile(_info, fileobj=_tempfile)
                logger_cli.debug("... created file '{}'".format(_filepath))
                self.basefile = _filepath

        elif not os.path.isfile(_filepath):
            # if path exists, and it is not a file
            raise ConfigException(
                "Supplied path of '{}' is not a file".format(
                    _filepath
                )
            )
        elif not tarfile.is_tarfile(_filepath):
            # if file exists, and it is not a tar file
            raise ConfigException(
                "Supplied file of '{}' is not a TAR stream".format(
                    _filepath
                )
            )
        else:
            self.basefile = _filepath

    def get_file(self, name, decode=False):
        if self.has_file(name):
            with tarfile.open(self.basefile, "r:gz") as tgz:
                _tgzitem = tgz.extractfile(tgz.getmember(name))
                if decode:
                    return _tgzitem.read().decode('utf-8')
                else:
                    return _tgzitem.read()
        else:
            return None

    def add_file(self, name, buf=None, replace=False):
        _files = []
        with tarfile.open(self.basefile) as r:
            _files = r.getnames()
            _exists = name in _files
            if _exists and not replace:
                # file exists and replace flag is not set
                return False

        # check if there is work to do
        if not buf and not os.path.exists(name):
            # Nothing to do: no buffer or file to add
            return False
        elif name in self.list_files() and not replace:
            # file already there and replace flag not set
            return False

        _a = "replace" if replace else "add"
        logger_cli.debug("... about to {} '{}' ({:.2f}MB) -> '{}'".format(
            _a,
            name,
            float(len(buf))/1024/1024,
            self.basefile
        ))

        # unzip tar, add file, zip it back
        _tmpdir = tempfile.mkdtemp()
        logger_cli.debug("... created tempdir '{}'".format(_tmpdir))
        # extract them
        _files = []
        with tarfile.open(self.basefile) as r:
            # all names extracted
            _files = r.getnames()
            # extract 'em
            logger_cli.debug("... extracting contents")
            r.extractall(_tmpdir)

        # create file
        if buf:
            _p = os.path.join(_tmpdir, name)
            logger_cli.debug("... writing new file to '{}'".format(
                _p
            ))
            if not _exists or replace:
                with open(_p, "w") as w:
                    w.write(buf)
            if not _exists:
                _files.append(name)
        # create the archive
        logger_cli.debug("... rebuilding archive")
        with tarfile.open(self.basefile, "w:gz") as tgz:
            for _file in _files:
                _p = os.path.join(_tmpdir, _file)
                tgz.add(_p, arcname=_file)
                os.remove(_p)
        os.rmdir(_tmpdir)
        return True

    def list_files(self):
        # get names
        with tarfile.open(self.basefile, "r:gz") as tgz:
            _names = tgz.getnames()
        # filter filenames only, skip path
        if any(['/' in _n for _n in _names]):
            _n = []
            for f in _names:
                if '/' in f:
                    _n.append(f.rsplit('/', 1)[1])
                else:
                    _n.append(f)
            _names = _n
        # remove label file from output
        if self._labelname in _names:
            _names.remove(self._labelname)
        return _names

    def has_file(self, name):
        if name in self.list_files():
            logger_cli.debug("... '{}' has '{}'".format(self.basefile, name))
            return True
        else:
            logger_cli.debug("... '{}' lacks '{}'".format(self.basefile, name))
            return False
