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,
                             standalone_tests = False)

    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,
                 standalone_tests = False):
        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
        self.standalone_tests = standalone_tests
        # 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)
        # List of tests to run early.
        self.early_tests = {}
        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)

