import os
import sys


class TestingConfig(object):
    """"
    TestingConfig - Information on the tests inside a suite.
    """

    @staticmethod
    def fromdefaults(litConfig):
        """
        fromdefaults(litConfig) -> TestingConfig

        Create a TestingConfig object with default values.
        """
        # Set the environment based on the command line arguments.
        environment = {
            'PATH' : os.pathsep.join(litConfig.path +
                                     [os.environ.get('PATH','')]),
            'LLVM_DISABLE_CRASH_REPORT' : '1',
            }

        pass_vars = ['LIBRARY_PATH', 'LD_LIBRARY_PATH', 'SYSTEMROOT', 'TERM',
                     'CLANG', 'LD_PRELOAD', 'ASAN_OPTIONS', 'UBSAN_OPTIONS',
                     'LSAN_OPTIONS', 'ADB', 'ANDROID_SERIAL', 'SSH_AUTH_SOCK',
                     'SANITIZER_IGNORE_CVE_2016_2143', 'TMPDIR', 'TMP', 'TEMP',
                     'TEMPDIR', 'AVRLIT_BOARD', 'AVRLIT_PORT',
                     'FILECHECK_OPTS', 'VCINSTALLDIR', 'VCToolsinstallDir',
                     'VSINSTALLDIR', 'WindowsSdkDir', 'WindowsSDKLibVersion']

        if sys.platform == 'win32':
            pass_vars.append('INCLUDE')
            pass_vars.append('LIB')
            pass_vars.append('PATHEXT')
            environment['PYTHONBUFFERED'] = '1'

        for var in pass_vars:
            val = os.environ.get(var, '')
            # Check for empty string as some variables such as LD_PRELOAD cannot be empty
            # ('') for OS's such as OpenBSD.
            if val:
                environment[var] = val

        # Set the default available features based on the LitConfig.
        available_features = []
        if litConfig.useValgrind:
            available_features.append('valgrind')
            if litConfig.valgrindLeakCheck:
                available_features.append('vg_leak')

        return TestingConfig(None,
                             name = '<unnamed>',
                             suffixes = set(),
                             test_format = None,
                             environment = environment,
                             substitutions = [],
                             unsupported = False,
                             test_exec_root = None,
                             test_source_root = None,
                             excludes = [],
                             available_features = available_features,
                             pipefail = True)

    def load_from_path(self, path, litConfig):
        """
        load_from_path(path, litConfig)

        Load the configuration module at the provided path into the given config
        object.
        """

        # Load the config script data.
        data = None
        f = open(path)
        try:
            data = f.read()
        except:
            litConfig.fatal('unable to load config file: %r' % (path,))
        f.close()

        # Execute the config script to initialize the object.
        cfg_globals = dict(globals())
        cfg_globals['config'] = self
        cfg_globals['lit_config'] = litConfig
        cfg_globals['__file__'] = path
        try:
            exec(compile(data, path, 'exec'), cfg_globals, None)
            if litConfig.debug:
                litConfig.note('... loaded config %r' % path)
        except SystemExit:
            e = sys.exc_info()[1]
            # We allow normal system exit inside a config file to just
            # return control without error.
            if e.args:
                raise
        except:
            import traceback
            litConfig.fatal(
                'unable to parse config file %r, traceback: %s' % (
                    path, traceback.format_exc()))
        self.finish(litConfig)

    def __init__(self, parent, name, suffixes, test_format,
                 environment, substitutions, unsupported,
                 test_exec_root, test_source_root, excludes,
                 available_features, pipefail, limit_to_features = [],
                 is_early = False, parallelism_group = None):
        self.parent = parent
        self.name = str(name)
        self.suffixes = set(suffixes)
        self.test_format = test_format
        self.environment = dict(environment)
        self.substitutions = list(substitutions)
        self.unsupported = unsupported
        self.test_exec_root = test_exec_root
        self.test_source_root = test_source_root
        self.excludes = set(excludes)
        self.available_features = set(available_features)
        self.pipefail = pipefail
        # This list is used by TestRunner.py to restrict running only tests that
        # require one of the features in this list if this list is non-empty.
        # Configurations can set this list to restrict the set of tests to run.
        self.limit_to_features = set(limit_to_features)
        # Whether the suite should be tested early in a given run.
        self.is_early = bool(is_early)
        self.parallelism_group = parallelism_group
        self._recursiveExpansionLimit = None

    @property
    def recursiveExpansionLimit(self):
        return self._recursiveExpansionLimit

    @recursiveExpansionLimit.setter
    def recursiveExpansionLimit(self, value):
        if value is not None and not isinstance(value, int):
            raise ValueError('recursiveExpansionLimit must be either None or an integer (got <{}>)'.format(value))
        if isinstance(value, int) and value < 0:
            raise ValueError('recursiveExpansionLimit must be a non-negative integer (got <{}>)'.format(value))
        self._recursiveExpansionLimit = value

    def finish(self, litConfig):
        """finish() - Finish this config object, after loading is complete."""

        self.name = str(self.name)
        self.suffixes = set(self.suffixes)
        self.environment = dict(self.environment)
        self.substitutions = list(self.substitutions)
        if self.test_exec_root is not None:
            # FIXME: This should really only be suite in test suite config
            # files. Should we distinguish them?
            self.test_exec_root = str(self.test_exec_root)
        if self.test_source_root is not None:
            # FIXME: This should really only be suite in test suite config
            # files. Should we distinguish them?
            self.test_source_root = str(self.test_source_root)
        self.excludes = set(self.excludes)

    @property
    def root(self):
        """root attribute - The root configuration for the test suite."""
        if self.parent is None:
            return self
        else:
            return self.parent.root

class SubstituteCaptures:
    """
    Helper class to indicate that the substitutions contains backreferences.

    This can be used as the following in lit.cfg to mark subsitutions as having
    back-references::

        config.substutions.append(('\b[^ ]*.cpp', SubstituteCaptures('\0.txt')))

    """
    def __init__(self, substitution):
        self.substitution = substitution

    def replace(self, pattern, replacement):
        return self.substitution

    def __str__(self):
        return self.substitution

    def __len__(self):
        return len(self.substitution)

    def __getitem__(self, item):
        return self.substitution.__getitem__(item)

