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')
            pass_vars.append('USERPROFILE')
            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)
        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)

