#!/usr/bin/env python

"""
This script determines the given package's openbmc dependencies from its
configure.ac file where it downloads, configures, builds, and installs each of
these dependencies. Then the given package is configured, built, and installed
prior to executing its unit tests.
"""

from git import Repo
from urlparse import urljoin
from subprocess import check_call, call, CalledProcessError
import os
import sys
import argparse
import multiprocessing
import re
import sets
import subprocess
import shutil
import platform


class DepTree():
    """
    Represents package dependency tree, where each node is a DepTree with a
    name and DepTree children.
    """

    def __init__(self, name):
        """
        Create new DepTree.

        Parameter descriptions:
        name               Name of new tree node.
        """
        self.name = name
        self.children = list()

    def AddChild(self, name):
        """
        Add new child node to current node.

        Parameter descriptions:
        name               Name of new child
        """
        new_child = DepTree(name)
        self.children.append(new_child)
        return new_child

    def AddChildNode(self, node):
        """
        Add existing child node to current node.

        Parameter descriptions:
        node               Tree node to add
        """
        self.children.append(node)

    def RemoveChild(self, name):
        """
        Remove child node.

        Parameter descriptions:
        name               Name of child to remove
        """
        for child in self.children:
            if child.name == name:
                self.children.remove(child)
                return

    def GetNode(self, name):
        """
        Return node with matching name. Return None if not found.

        Parameter descriptions:
        name               Name of node to return
        """
        if self.name == name:
            return self
        for child in self.children:
            node = child.GetNode(name)
            if node:
                return node
        return None

    def GetParentNode(self, name, parent_node=None):
        """
        Return parent of node with matching name. Return none if not found.

        Parameter descriptions:
        name               Name of node to get parent of
        parent_node        Parent of current node
        """
        if self.name == name:
            return parent_node
        for child in self.children:
            found_node = child.GetParentNode(name, self)
            if found_node:
                return found_node
        return None

    def GetPath(self, name, path=None):
        """
        Return list of node names from head to matching name.
        Return None if not found.

        Parameter descriptions:
        name               Name of node
        path               List of node names from head to current node
        """
        if not path:
            path = []
        if self.name == name:
            path.append(self.name)
            return path
        for child in self.children:
            match = child.GetPath(name, path + [self.name])
            if match:
                return match
        return None

    def GetPathRegex(self, name, regex_str, path=None):
        """
        Return list of node paths that end in name, or match regex_str.
        Return empty list if not found.

        Parameter descriptions:
        name               Name of node to search for
        regex_str          Regex string to match node names
        path               Path of node names from head to current node
        """
        new_paths = []
        if not path:
            path = []
        match = re.match(regex_str, self.name)
        if (self.name == name) or (match):
            new_paths.append(path + [self.name])
        for child in self.children:
            return_paths = None
            full_path = path + [self.name]
            return_paths = child.GetPathRegex(name, regex_str, full_path)
            for i in return_paths:
                new_paths.append(i)
        return new_paths

    def MoveNode(self, from_name, to_name):
        """
        Mode existing from_name node to become child of to_name node.

        Parameter descriptions:
        from_name          Name of node to make a child of to_name
        to_name            Name of node to make parent of from_name
        """
        parent_from_node = self.GetParentNode(from_name)
        from_node = self.GetNode(from_name)
        parent_from_node.RemoveChild(from_name)
        to_node = self.GetNode(to_name)
        to_node.AddChildNode(from_node)

    def ReorderDeps(self, name, regex_str):
        """
        Reorder dependency tree.  If tree contains nodes with names that
        match 'name' and 'regex_str', move 'regex_str' nodes that are
        to the right of 'name' node, so that they become children of the
        'name' node.

        Parameter descriptions:
        name               Name of node to look for
        regex_str          Regex string to match names to
        """
        name_path = self.GetPath(name)
        if not name_path:
            return
        paths = self.GetPathRegex(name, regex_str)
        is_name_in_paths = False
        name_index = 0
        for i in range(len(paths)):
            path = paths[i]
            if path[-1] == name:
                is_name_in_paths = True
                name_index = i
                break
        if not is_name_in_paths:
            return
        for i in range(name_index + 1, len(paths)):
            path = paths[i]
            if name in path:
                continue
            from_name = path[-1]
            self.MoveNode(from_name, name)

    def GetInstallList(self):
        """
        Return post-order list of node names.

        Parameter descriptions:
        """
        install_list = []
        for child in self.children:
            child_install_list = child.GetInstallList()
            install_list.extend(child_install_list)
        install_list.append(self.name)
        return install_list

    def PrintTree(self, level=0):
        """
        Print pre-order node names with indentation denoting node depth level.

        Parameter descriptions:
        level              Current depth level
        """
        INDENT_PER_LEVEL = 4
        print ' ' * (level * INDENT_PER_LEVEL) + self.name
        for child in self.children:
            child.PrintTree(level + 1)


def check_call_cmd(*cmd):
    """
    Verbose prints the directory location the given command is called from and
    the command, then executes the command using check_call.

    Parameter descriptions:
    dir                 Directory location command is to be called from
    cmd                 List of parameters constructing the complete command
    """
    printline(os.getcwd(), ">", " ".join(cmd))
    check_call(cmd)


def clone_pkg(pkg, branch):
    """
    Clone the given openbmc package's git repository from gerrit into
    the WORKSPACE location

    Parameter descriptions:
    pkg                 Name of the package to clone
    branch              Branch to clone from pkg
    """
    pkg_dir = os.path.join(WORKSPACE, pkg)
    if os.path.exists(os.path.join(pkg_dir, '.git')):
        return pkg_dir
    pkg_repo = urljoin('https://gerrit.openbmc-project.xyz/openbmc/', pkg)
    os.mkdir(pkg_dir)
    printline(pkg_dir, "> git clone", pkg_repo, branch, "./")
    try:
        # first try the branch
        repo_inst = Repo.clone_from(pkg_repo, pkg_dir,
                branch=branch).working_dir
    except:
        printline("Input branch not found, default to master")
        repo_inst = Repo.clone_from(pkg_repo, pkg_dir,
                branch="master").working_dir
    return repo_inst


def make_target_exists(target):
    """
    Runs a check against the makefile in the current directory to determine
    if the target exists so that it can be built.

    Parameter descriptions:
    target              The make target we are checking
    """
    try:
        cmd = [ 'make', '-n', target ]
        with open(os.devnull, 'w') as devnull:
            check_call(cmd, stdout=devnull, stderr=devnull)
        return True
    except CalledProcessError:
        return False


make_parallel = [
    'make',
    # Run enough jobs to saturate all the cpus
    '-j', str(multiprocessing.cpu_count()),
    # Don't start more jobs if the load avg is too high
    '-l', str(multiprocessing.cpu_count()),
    # Synchronize the output so logs aren't intermixed in stdout / stderr
    '-O',
]


def build_and_install(name, build_for_testing=False):
    """
    Builds and installs the package in the environment. Optionally
    builds the examples and test cases for package.

    Parameter description:
    name                The name of the package we are building
    build_for_testing   Enable options related to testing on the package?
    """
    os.chdir(os.path.join(WORKSPACE, name))

    # Refresh dynamic linker run time bindings for dependencies
    check_call_cmd('sudo', '-n', '--', 'ldconfig')

    pkg = Package()
    if build_for_testing:
        pkg.test()
    else:
        pkg.install()


def build_dep_tree(name, pkgdir, dep_added, head, branch, dep_tree=None):
    """
    For each package (name), starting with the package to be unit tested,
    extract its dependencies. For each package dependency defined, recursively
    apply the same strategy

    Parameter descriptions:
    name                Name of the package
    pkgdir              Directory where package source is located
    dep_added           Current dict of dependencies and added status
    head                Head node of the dependency tree
    branch              Branch to clone from pkg
    dep_tree            Current dependency tree node
    """
    if not dep_tree:
        dep_tree = head

    with open("/tmp/depcache", "r") as depcache:
        cache = depcache.readline()

    # Read out pkg dependencies
    pkg = Package(name, pkgdir)

    for dep in sets.Set(pkg.build_system().dependencies()):
        if dep in cache:
            continue
        # Dependency package not already known
        if dep_added.get(dep) is None:
            # Dependency package not added
            new_child = dep_tree.AddChild(dep)
            dep_added[dep] = False
            dep_pkgdir = clone_pkg(dep,branch)
            # Determine this dependency package's
            # dependencies and add them before
            # returning to add this package
            dep_added = build_dep_tree(dep,
                                       dep_pkgdir,
                                       dep_added,
                                       head,
                                       branch,
                                       new_child)
        else:
            # Dependency package known and added
            if dep_added[dep]:
                continue
            else:
                # Cyclic dependency failure
                raise Exception("Cyclic dependencies found in "+name)

    if not dep_added[name]:
        dep_added[name] = True

    return dep_added


def run_cppcheck():
    match_re = re.compile('((?!\.mako\.).)*\.[ch](?:pp)?$', re.I)
    cppcheck_files = []
    stdout = subprocess.check_output(['git', 'ls-files'])

    for f in stdout.decode('utf-8').split():
        if match_re.match(f):
            cppcheck_files.append(f)

    if not cppcheck_files:
        # skip cppcheck if there arent' any c or cpp sources.
        print("no files")
        return None

    # http://cppcheck.sourceforge.net/manual.pdf
    params = ['cppcheck', '-j', str(multiprocessing.cpu_count()),
              '--enable=all', '--file-list=-']

    cppcheck_process = subprocess.Popen(
        params,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        stdin=subprocess.PIPE)
    (stdout, stderr) = cppcheck_process.communicate(
        input='\n'.join(cppcheck_files))

    if cppcheck_process.wait():
        raise Exception('Cppcheck failed')
    print(stdout)
    print(stderr)

def is_valgrind_safe():
    """
    Returns whether it is safe to run valgrind on our platform
    """
    src = 'unit-test-vg.c'
    exe = './unit-test-vg'
    with open(src, 'w') as h:
        h.write('#include <errno.h>\n')
        h.write('#include <stdio.h>\n')
        h.write('#include <stdlib.h>\n')
        h.write('#include <string.h>\n')
        h.write('int main() {\n')
        h.write('char *heap_str = malloc(16);\n')
        h.write('strcpy(heap_str, "RandString");\n')
        h.write('int res = strcmp("RandString", heap_str);\n')
        h.write('free(heap_str);\n')
        h.write('char errstr[64];\n')
        h.write('strerror_r(EINVAL, errstr, sizeof(errstr));\n')
        h.write('printf("%s\\n", errstr);\n')
        h.write('return res;\n')
        h.write('}\n')
    try:
        with open(os.devnull, 'w') as devnull:
            check_call(['gcc', '-O2', '-o', exe, src],
                       stdout=devnull, stderr=devnull)
            check_call(['valgrind', '--error-exitcode=99', exe],
                       stdout=devnull, stderr=devnull)
        return True
    except:
        sys.stderr.write("###### Platform is not valgrind safe ######\n")
        return False
    finally:
        os.remove(src)
        os.remove(exe)

def is_sanitize_safe():
    """
    Returns whether it is safe to run sanitizers on our platform
    """
    src = 'unit-test-sanitize.c'
    exe = './unit-test-sanitize'
    with open(src, 'w') as h:
        h.write('int main() { return 0; }\n')
    try:
        with open(os.devnull, 'w') as devnull:
            check_call(['gcc', '-O2', '-fsanitize=address',
                        '-fsanitize=undefined', '-o', exe, src],
                       stdout=devnull, stderr=devnull)
            check_call([exe], stdout=devnull, stderr=devnull)
        return True
    except:
        sys.stderr.write("###### Platform is not sanitize safe ######\n")
        return False
    finally:
        os.remove(src)
        os.remove(exe)


def maybe_make_valgrind():
    """
    Potentially runs the unit tests through valgrind for the package
    via `make check-valgrind`. If the package does not have valgrind testing
    then it just skips over this.
    """
    # Valgrind testing is currently broken by an aggressive strcmp optimization
    # that is inlined into optimized code for POWER by gcc 7+. Until we find
    # a workaround, just don't run valgrind tests on POWER.
    # https://github.com/openbmc/openbmc/issues/3315
    if not is_valgrind_safe():
        sys.stderr.write("###### Skipping valgrind ######\n")
        return
    if not make_target_exists('check-valgrind'):
        return

    try:
        cmd = make_parallel + [ 'check-valgrind' ]
        check_call_cmd(*cmd)
    except CalledProcessError:
        for root, _, files in os.walk(os.getcwd()):
            for f in files:
                if re.search('test-suite-[a-z]+.log', f) is None:
                    continue
                check_call_cmd('cat', os.path.join(root, f))
        raise Exception('Valgrind tests failed')

def maybe_make_coverage():
    """
    Potentially runs the unit tests through code coverage for the package
    via `make check-code-coverage`. If the package does not have code coverage
    testing then it just skips over this.
    """
    if not make_target_exists('check-code-coverage'):
        return

    # Actually run code coverage
    try:
        cmd = make_parallel + [ 'check-code-coverage' ]
        check_call_cmd(*cmd)
    except CalledProcessError:
        raise Exception('Code coverage failed')


class BuildSystem(object):
    """
    Build systems generally provide the means to configure, build, install and
    test software. The BuildSystem class defines a set of interfaces on top of
    which Autotools, Meson, CMake and possibly other build system drivers can
    be implemented, separating out the phases to control whether a package
    should merely be installed or also tested and analyzed.
    """
    def __init__(self, package, path):
        """Initialise the driver with properties independent of the build system

        Keyword arguments:
        package: The name of the package. Derived from the path if None
        path: The path to the package. Set to the working directory if None
        """
        self.path = "." if not path else path
        self.package = package if package else os.path.basename(os.path.realpath(self.path))
        self.build_for_testing=False

    def probe(self):
        """Test if the build system driver can be applied to the package

        Return True if the driver can drive the package's build system,
        otherwise False.

        Generally probe() is implemented by testing for the presence of the
        build system's configuration file(s).
        """
        raise NotImplemented

    def dependencies(self):
        """Provide the package's dependencies

        Returns a list of dependencies. If no dependencies are required then an
        empty list must be returned.

        Generally dependencies() is implemented by analysing and extracting the
        data from the build system configuration.
        """
        raise NotImplemented

    def configure(self, build_for_testing):
        """Configure the source ready for building

        Should raise an exception if configuration failed.

        Keyword arguments:
        build_for_testing: Mark the package as being built for testing rather
                           than for installation as a dependency for the
                           package under test. Setting to True generally
                           implies that the package will be configured to build
                           with debug information, at a low level of
                           optimisation and possibly with sanitizers enabled.

        Generally configure() is implemented by invoking the build system
        tooling to generate Makefiles or equivalent.
        """
        raise NotImplemented

    def build(self):
        """Build the software ready for installation and/or testing

        Should raise an exception if the build fails

        Generally build() is implemented by invoking `make` or `ninja`.
        """
        raise NotImplemented

    def install(self):
        """Install the software ready for use

        Should raise an exception if installation fails

        Like build(), install() is generally implemented by invoking `make` or
        `ninja`.
        """
        raise NotImplemented

    def test(self):
        """Build and run the test suite associated with the package

        Should raise an exception if the build or testing fails.

        Like install(), test() is generally implemented by invoking `make` or
        `ninja`.
        """
        raise NotImplemented

    def analyze(self):
        """Run any supported analysis tools over the codebase

        Should raise an exception if analysis fails.

        Some analysis tools such as scan-build need injection into the build
        system. analyze() provides the necessary hook to implement such
        behaviour. Analyzers independent of the build system can also be
        specified here but at the cost of possible duplication of code between
        the build system driver implementations.
        """
        raise NotImplemented


class Autotools(BuildSystem):
    def __init__(self, package=None, path=None):
        super(Autotools, self).__init__(package, path)

    def probe(self):
        return os.path.isfile(os.path.join(self.path, 'configure.ac'))

    def dependencies(self):
        configure_ac = os.path.join(self.path, 'configure.ac')

        configure_ac_contents = ''
        # Prepend some special function overrides so we can parse out dependencies
        for macro in DEPENDENCIES.iterkeys():
            configure_ac_contents += ('m4_define([' + macro + '], [' +
                    macro + '_START$' + str(DEPENDENCIES_OFFSET[macro] + 1) +
                    macro + '_END])\n')
        with open(configure_ac, "rt") as f:
            configure_ac_contents += f.read()

        autoconf_process = subprocess.Popen(['autoconf', '-Wno-undefined', '-'],
                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                stderr=subprocess.PIPE)
        (stdout, stderr) = autoconf_process.communicate(input=configure_ac_contents)
        if not stdout:
            print(stderr)
            raise Exception("Failed to run autoconf for parsing dependencies")

        # Parse out all of the dependency text
        matches = []
        for macro in DEPENDENCIES.iterkeys():
            pattern = '(' + macro + ')_START(.*?)' + macro + '_END'
            for match in re.compile(pattern).finditer(stdout):
                matches.append((match.group(1), match.group(2)))

        # Look up dependencies from the text
        found_deps = []
        for macro, deptext in matches:
            for potential_dep in deptext.split(' '):
                for known_dep in DEPENDENCIES[macro].iterkeys():
                    if potential_dep.startswith(known_dep):
                        found_deps.append(DEPENDENCIES[macro][known_dep])

        return found_deps

    def _configure_feature(self, flag, enabled):
        """
        Returns an configure flag as a string

        Parameters:
        flag                The name of the flag
        enabled             Whether the flag is enabled or disabled
        """
        return '--' + ('enable' if enabled else 'disable') + '-' + flag

    def configure(self, build_for_testing):
        self.build_for_testing = build_for_testing
        conf_flags = [
            self._configure_feature('silent-rules', False),
            self._configure_feature('examples', build_for_testing),
            self._configure_feature('tests', build_for_testing),
        ]
        if not TEST_ONLY:
            conf_flags.extend([
                self._configure_feature('code-coverage', build_for_testing),
                self._configure_feature('valgrind', build_for_testing),
            ])
        # Add any necessary configure flags for package
        if CONFIGURE_FLAGS.get(self.package) is not None:
            conf_flags.extend(CONFIGURE_FLAGS.get(self.package))
        for bootstrap in ['bootstrap.sh', 'bootstrap', 'autogen.sh']:
            if os.path.exists(bootstrap):
                check_call_cmd('./' + bootstrap)
                break
        check_call_cmd('./configure', *conf_flags)

    def build(self):
        check_call_cmd(*make_parallel)

    def install(self):
        check_call_cmd('sudo', '-n', '--', *(make_parallel + [ 'install' ]))

    def test(self):
        try:
            cmd = make_parallel + [ 'check' ]
            for i in range(0, args.repeat):
                check_call_cmd(*cmd)
        except CalledProcessError:
            for root, _, files in os.walk(os.getcwd()):
                if 'test-suite.log' not in files:
                    continue
                check_call_cmd('cat', os.path.join(root, 'test-suite.log'))
            raise Exception('Unit tests failed')

    def analyze(self):
        maybe_make_valgrind()
        maybe_make_coverage()
        run_cppcheck()


class CMake(BuildSystem):
    def __init__(self, package=None, path=None):
        super(CMake, self).__init__(package, path)

    def probe(self):
        return os.path.isfile(os.path.join(self.path, 'CMakeLists.txt'))

    def dependencies(self):
        return []

    def configure(self, build_for_testing):
        self.build_for_testing = build_for_testing
        check_call_cmd('cmake', '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON', '.')

    def build(self):
        check_call_cmd('cmake', '--build', '.', '--', '-j',
                       str(multiprocessing.cpu_count()))

    def install(self):
        pass

    def test(self):
        if make_target_exists('test'):
            check_call_cmd('ctest', '.')

    def analyze(self):
        if os.path.isfile('.clang-tidy'):
            check_call_cmd('run-clang-tidy-8.py', '-p', '.')
        maybe_make_valgrind()
        maybe_make_coverage()
        run_cppcheck()


class Meson(BuildSystem):
    def __init__(self, package=None, path=None):
        super(Meson, self).__init__(package, path)

    def probe(self):
        return os.path.isfile(os.path.join(self.path, 'meson.build'))

    def dependencies(self):
        meson_build = os.path.join(self.path, 'meson.build')
        if not os.path.exists(meson_build):
            return []

        found_deps = []
        for root, dirs, files in os.walk(self.path):
            if 'meson.build' not in files:
                continue
            with open(os.path.join(root, 'meson.build'), 'rt') as f:
                build_contents = f.read()
            for match in re.finditer(r"dependency\('([^']*)'.*?\)\n", build_contents):
                maybe_dep = DEPENDENCIES['PKG_CHECK_MODULES'].get(match.group(1))
                if maybe_dep is not None:
                    found_deps.append(maybe_dep)

        return found_deps

    def _parse_options(self, options_file):
        """
        Returns a set of options defined in the provides meson_options.txt file

        Parameters:
        options_file        The file containing options
        """
        options_contents = ''
        with open(options_file, "rt") as f:
            options_contents += f.read()
        options = sets.Set()
        pattern = 'option\\(\\s*\'([^\']*)\''
        for match in re.compile(pattern).finditer(options_contents):
            options.add(match.group(1))
        return options

    def _configure_feature(self, val):
        """
        Returns the meson flag which signifies the value

        True is enabled which requires the feature.
        False is disabled which disables the feature.
        None is auto which autodetects the feature.

        Parameters:
        val                 The value being converted
        """
        if val is True:
            return "enabled"
        elif val is False:
            return "disabled"
        elif val is None:
            return "auto"
        else:
            raise Exception("Bad meson feature value")

    def configure(self, build_for_testing):
        self.build_for_testing = build_for_testing
        meson_options = sets.Set()
        if os.path.exists("meson_options.txt"):
            meson_options = self._parse_options("meson_options.txt")
        meson_flags = [
            '-Db_colorout=never',
            '-Dwerror=true',
            '-Dwarning_level=3',
        ]
        if build_for_testing:
            meson_flags.append('--buildtype=debug')
        else:
            meson_flags.append('--buildtype=debugoptimized')
        if 'tests' in meson_options:
            meson_flags.append('-Dtests=' + self._configure_feature(build_for_testing))
        if 'examples' in meson_options:
            meson_flags.append('-Dexamples=' + str(build_for_testing).lower())
        if MESON_FLAGS.get(self.package) is not None:
            meson_flags.extend(MESON_FLAGS.get(self.package))
        try:
            check_call_cmd('meson', 'setup', '--reconfigure', 'build', *meson_flags)
        except:
            shutil.rmtree('build')
            check_call_cmd('meson', 'setup', 'build', *meson_flags)

    def build(self):
        check_call_cmd('ninja', '-C', 'build')

    def install(self):
        check_call_cmd('sudo', '-n', '--', 'ninja', '-C', 'build', 'install')

    def test(self):
        try:
            check_call_cmd('meson', 'test', '-C', 'build')
        except CalledProcessError:
            for root, _, files in os.walk(os.getcwd()):
                if 'testlog.txt' not in files:
                    continue
                check_call_cmd('cat', os.path.join(root, 'testlog.txt'))
            raise Exception('Unit tests failed')

    def _setup_exists(self, setup):
        """
        Returns whether the meson build supports the named test setup.

        Parameter descriptions:
        setup              The setup target to check
        """
        try:
            with open(os.devnull, 'w') as devnull:
                output = subprocess.check_output(
                        ['meson', 'test', '-C', 'build',
                         '--setup', setup, '-t', '0'],
                        stderr=subprocess.STDOUT)
        except CalledProcessError as e:
            output = e.output
        return not re.search('Test setup .* not found from project', output)

    def _maybe_valgrind(self):
        """
        Potentially runs the unit tests through valgrind for the package
        via `meson test`. The package can specify custom valgrind configurations
        by utilizing add_test_setup() in a meson.build
        """
        if not is_valgrind_safe():
            sys.stderr.write("###### Skipping valgrind ######\n")
            return
        try:
            if self._setup_exists('valgrind'):
                check_call_cmd('meson', 'test', '-C', 'build',
                               '--setup', 'valgrind')
            else:
                check_call_cmd('meson', 'test', '-C', 'build',
                               '--wrapper', 'valgrind')
        except CalledProcessError:
            for root, _, files in os.walk(os.getcwd()):
                if 'testlog-valgrind.txt' not in files:
                    continue
                check_call_cmd('cat', os.path.join(root, 'testlog-valgrind.txt'))
            raise Exception('Valgrind tests failed')

    def analyze(self):
        self._maybe_valgrind()

        # Run clang-tidy only if the project has a configuration
        if os.path.isfile('.clang-tidy'):
            check_call_cmd('run-clang-tidy-8.py', '-p',
                           'build')
        # Run the basic clang static analyzer otherwise
        else:
            check_call_cmd('ninja', '-C', 'build',
                           'scan-build')

        # Run tests through sanitizers
        # b_lundef is needed if clang++ is CXX since it resolves the
        # asan symbols at runtime only. We don't want to set it earlier
        # in the build process to ensure we don't have undefined
        # runtime code.
        if is_sanitize_safe():
            check_call_cmd('meson', 'configure', 'build',
                           '-Db_sanitize=address,undefined',
                           '-Db_lundef=false')
            check_call_cmd('meson', 'test', '-C', 'build',
                           '--logbase', 'testlog-ubasan')
            # TODO: Fix memory sanitizer
            #check_call_cmd('meson', 'configure', 'build',
            #               '-Db_sanitize=memory')
            #check_call_cmd('meson', 'test', '-C', 'build'
            #               '--logbase', 'testlog-msan')
            check_call_cmd('meson', 'configure', 'build',
                           '-Db_sanitize=none', '-Db_lundef=true')
        else:
            sys.stderr.write("###### Skipping sanitizers ######\n")

        # Run coverage checks
        check_call_cmd('meson', 'configure', 'build',
                       '-Db_coverage=true')
        self.test()
        # Only build coverage HTML if coverage files were produced
        for root, dirs, files in os.walk('build'):
            if any([f.endswith('.gcda') for f in files]):
                check_call_cmd('ninja', '-C', 'build',
                               'coverage-html')
                break
        check_call_cmd('meson', 'configure', 'build',
                       '-Db_coverage=false')
        run_cppcheck()


class Package(object):
    def __init__(self, name=None, path=None):
        self.supported = [ Autotools, Meson, CMake ]
        self.name = name
        self.path = path
        self.test_only = False

    def build_systems(self):
        instances = ( system(self.name, self.path) for system in self.supported )
        return ( instance for instance in instances if instance.probe() )

    def build_system(self, preferred=None):
        systems = self.build_systems()

        if preferred:
            return { type(system): system for system in systems }[preferred]

        return next(iter(systems))

    def install(self, system=None):
        if not system:
            system = self.build_system()

        system.configure(False)
        system.build()
        system.install()

    def test(self):
        system = self.build_system()
        system.configure(True)
        system.build()
        system.install()
        system.test()
        system.analyze()


def find_file(filename, basedir):
    """
    Finds all occurrences of a file in the base directory
    and passes them back with their relative paths.

    Parameter descriptions:
    filename              The name of the file to find
    basedir               The base directory search in
    """

    filepaths = []
    for root, dirs, files in os.walk(basedir):
        if filename in files:
                filepaths.append(os.path.join(root, filename))
    return filepaths

if __name__ == '__main__':
    # CONFIGURE_FLAGS = [GIT REPO]:[CONFIGURE FLAGS]
    CONFIGURE_FLAGS = {
        'sdbusplus': ['--enable-transaction'],
        'phosphor-logging':
        ['--enable-metadata-processing', '--enable-openpower-pel-extension',
         'YAML_DIR=/usr/local/share/phosphor-dbus-yaml/yaml']
    }

    # MESON_FLAGS = [GIT REPO]:[MESON FLAGS]
    MESON_FLAGS = {
    }

    # DEPENDENCIES = [MACRO]:[library/header]:[GIT REPO]
    DEPENDENCIES = {
        'AC_CHECK_LIB': {'mapper': 'phosphor-objmgr'},
        'AC_CHECK_HEADER': {
            'host-ipmid': 'phosphor-host-ipmid',
            'blobs-ipmid': 'phosphor-ipmi-blobs',
            'sdbusplus': 'sdbusplus',
            'sdeventplus': 'sdeventplus',
            'stdplus': 'stdplus',
            'gpioplus': 'gpioplus',
            'phosphor-logging/log.hpp': 'phosphor-logging',
        },
        'AC_PATH_PROG': {'sdbus++': 'sdbusplus'},
        'PKG_CHECK_MODULES': {
            'phosphor-dbus-interfaces': 'phosphor-dbus-interfaces',
            'openpower-dbus-interfaces': 'openpower-dbus-interfaces',
            'ibm-dbus-interfaces': 'ibm-dbus-interfaces',
            'libipmid': 'phosphor-host-ipmid',
            'libipmid-host': 'phosphor-host-ipmid',
            'sdbusplus': 'sdbusplus',
            'sdeventplus': 'sdeventplus',
            'stdplus': 'stdplus',
            'gpioplus': 'gpioplus',
            'phosphor-logging': 'phosphor-logging',
            'phosphor-snmp': 'phosphor-snmp',
            'ipmiblob': 'ipmi-blob-tool',
        },
    }

    # Offset into array of macro parameters MACRO(0, 1, ...N)
    DEPENDENCIES_OFFSET = {
        'AC_CHECK_LIB': 0,
        'AC_CHECK_HEADER': 0,
        'AC_PATH_PROG': 1,
        'PKG_CHECK_MODULES': 1,
    }

    # DEPENDENCIES_REGEX = [GIT REPO]:[REGEX STRING]
    DEPENDENCIES_REGEX = {
        'phosphor-logging': r'\S+-dbus-interfaces$'
    }

    # Set command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("-w", "--workspace", dest="WORKSPACE", required=True,
                        help="Workspace directory location(i.e. /home)")
    parser.add_argument("-p", "--package", dest="PACKAGE", required=True,
                        help="OpenBMC package to be unit tested")
    parser.add_argument("-t", "--test-only", dest="TEST_ONLY",
                        action="store_true", required=False, default=False,
                        help="Only run test cases, no other validation")
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="Print additional package status messages")
    parser.add_argument("-r", "--repeat", help="Repeat tests N times",
                        type=int, default=1)
    parser.add_argument("-b", "--branch", dest="BRANCH", required=False,
                        help="Branch to target for dependent repositories",
                        default="master")
    parser.add_argument("-n", "--noformat", dest="FORMAT",
                        action="store_false", required=False,
                        help="Whether or not to run format code")
    args = parser.parse_args(sys.argv[1:])
    WORKSPACE = args.WORKSPACE
    UNIT_TEST_PKG = args.PACKAGE
    TEST_ONLY = args.TEST_ONLY
    BRANCH = args.BRANCH
    FORMAT_CODE = args.FORMAT
    if args.verbose:
        def printline(*line):
            for arg in line:
                print arg,
            print
    else:
        printline = lambda *l: None

    CODE_SCAN_DIR = WORKSPACE + "/" + UNIT_TEST_PKG

    # First validate code formatting if repo has style formatting files.
    # The format-code.sh checks for these files.
    if FORMAT_CODE:
        check_call_cmd("./format-code.sh", CODE_SCAN_DIR)

    prev_umask = os.umask(000)

    # Determine dependencies and add them
    dep_added = dict()
    dep_added[UNIT_TEST_PKG] = False

    # Create dependency tree
    dep_tree = DepTree(UNIT_TEST_PKG)
    build_dep_tree(UNIT_TEST_PKG,
                   os.path.join(WORKSPACE, UNIT_TEST_PKG),
                   dep_added,
                   dep_tree,
                   BRANCH)

    # Reorder Dependency Tree
    for pkg_name, regex_str in DEPENDENCIES_REGEX.iteritems():
        dep_tree.ReorderDeps(pkg_name, regex_str)
    if args.verbose:
        dep_tree.PrintTree()

    install_list = dep_tree.GetInstallList()

    # We don't want to treat our package as a dependency
    install_list.remove(UNIT_TEST_PKG)

    # Install reordered dependencies
    for dep in install_list:
        build_and_install(dep, False)

    # Run package unit tests
    build_and_install(UNIT_TEST_PKG, True)

    os.umask(prev_umask)

    # Run any custom CI scripts the repo has, of which there can be
    # multiple of and anywhere in the repository.
    ci_scripts = find_file('run-ci.sh', os.path.join(WORKSPACE, UNIT_TEST_PKG))
    if ci_scripts:
        os.chdir(os.path.join(WORKSPACE, UNIT_TEST_PKG))
        for ci_script in ci_scripts:
            check_call_cmd('sh', ci_script)
