import contextlib
import logging
import os
import subprocess
import shlex
import sys
import sysconfig
import tempfile
import venv


class VirtualEnvironment:
    def __init__(self, prefix, **venv_create_args):
        self._logger = logging.getLogger(self.__class__.__name__)
        venv.create(prefix, **venv_create_args)
        self._prefix = prefix
        self._paths = sysconfig.get_paths(
            scheme='venv',
            vars={'base': self.prefix},
            expand=True,
        )

    @classmethod
    @contextlib.contextmanager
    def from_tmpdir(cls, *, prefix=None, dir=None, **venv_create_args):
        delete = not bool(os.environ.get('PYTHON_TESTS_KEEP_VENV'))
        with tempfile.TemporaryDirectory(prefix=prefix, dir=dir, delete=delete) as tmpdir:
            yield cls(tmpdir, **venv_create_args)

    @property
    def prefix(self):
        return self._prefix

    @property
    def paths(self):
        return self._paths

    @property
    def interpreter(self):
        return os.path.join(self.paths['scripts'], os.path.basename(sys.executable))

    def _format_output(self, name, data, indent='\t'):
        if not data:
            return indent + f'{name}: (none)'
        if len(data.splitlines()) == 1:
            return indent + f'{name}: {data}'
        else:
            prefixed_lines = '\n'.join(indent + '> ' + line for line in data.splitlines())
            return indent + f'{name}:\n' + prefixed_lines

    def run(self, *args, **subprocess_args):
        if subprocess_args.get('shell'):
            raise ValueError('Running the subprocess in shell mode is not supported.')
        default_args = {
            'capture_output': True,
            'check': True,
        }
        try:
            result = subprocess.run([self.interpreter, *args], **default_args | subprocess_args)
        except subprocess.CalledProcessError as e:
            if e.returncode != 0:
                self._logger.error(
                    f'Interpreter returned non-zero exit status {e.returncode}.\n'
                    + self._format_output('COMMAND', shlex.join(e.cmd)) + '\n'
                    + self._format_output('STDOUT', e.stdout.decode()) + '\n'
                    + self._format_output('STDERR', e.stderr.decode()) + '\n'
                )
            raise
        else:
            return result


class VirtualEnvironmentMixin:
    def venv(self, name=None, **venv_create_args):
        venv_name = self.id()
        if name:
            venv_name += f'-{name}'
        return VirtualEnvironment.from_tmpdir(
            prefix=f'{venv_name}-venv-',
            **venv_create_args,
        )
