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', 'LLDB', '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', 'SOURCE_DATE_EPOCH']

        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)

