#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# Copyright 2016-2021 The Meson development team

# Work around some pathlib bugs...
from mesonbuild import _pathlib
import sys
sys.modules['pathlib'] = _pathlib

import time
import subprocess
import os
import unittest

import mesonbuild.mlog
import mesonbuild.depfile
import mesonbuild.dependencies.base
import mesonbuild.dependencies.factory
import mesonbuild.compilers
import mesonbuild.envconfig
import mesonbuild.environment
import mesonbuild.coredata
import mesonbuild.modules.gnome
from mesonbuild.mesonlib import python_command, setup_vsenv
import mesonbuild.modules.pkgconfig

from unittests.allplatformstests import AllPlatformTests
from unittests.cargotests import CargoVersionTest, CargoCfgTest
from unittests.darwintests import DarwinTests
from unittests.failuretests import FailureTests
from unittests.linuxcrosstests import LinuxCrossArmTests, LinuxCrossMingwTests
from unittests.machinefiletests import NativeFileTests, CrossFileTests
from unittests.rewritetests import RewriterTests
from unittests.taptests import TAPParserTests
from unittests.datatests import DataTests
from unittests.internaltests import InternalTests
from unittests.linuxliketests import LinuxlikeTests
from unittests.pythontests import PythonTests
from unittests.subprojectscommandtests import SubprojectsCommandTests
from unittests.windowstests import WindowsTests
from unittests.platformagnostictests import PlatformAgnosticTests

def unset_envs():
    # For unit tests we must fully control all command lines
    # so that there are no unexpected changes coming from the
    # environment, for example when doing a package build.
    varnames = ['CPPFLAGS', 'LDFLAGS'] + list(mesonbuild.compilers.compilers.CFLAGS_MAPPING.values())
    for v in varnames:
        if v in os.environ:
            del os.environ[v]

def convert_args(argv):
    # If we got passed a list of tests, pass it on
    pytest_args = ['-v'] if '-v' in argv else []
    test_list = []
    for arg in argv:
        if arg.startswith('-'):
            if arg in ('-f', '--failfast'):
                arg = '--exitfirst'
            pytest_args.append(arg)
            continue
        # ClassName.test_name => 'ClassName and test_name'
        if '.' in arg:
            arg = ' and '.join(arg.split('.'))
        test_list.append(arg)
    if test_list:
        pytest_args += ['-k', ' or '.join(test_list)]
    return pytest_args

def running_single_tests(argv, cases):
    '''
    Check whether we only got arguments for running individual tests, not
    entire testcases, and not all testcases (no test args).
    '''
    got_test_arg = False
    for arg in argv:
        if arg.startswith('-'):
            continue
        for case in cases:
            if not arg.startswith(case):
                continue
            if '.' not in arg:
                # Got a testcase, done
                return False
            got_test_arg = True
    return got_test_arg

def setup_backend():
    filtered = []
    be = 'ninja'
    for a in sys.argv:
        if a.startswith('--backend'):
            be = a.split('=')[1]
        else:
            filtered.append(a)
    # Since we invoke the tests via unittest or xtest test runner
    # we need to pass the backend to use to the spawned process via
    # this side channel. Yes it sucks, but at least is is fully
    # internal to this file.
    os.environ['MESON_UNIT_TEST_BACKEND'] = be
    sys.argv = filtered

def main():
    unset_envs()
    setup_backend()
    cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests',
             'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests',
             'TAPParserTests', 'SubprojectsCommandTests', 'PlatformAgnosticTests',

             'LinuxlikeTests', 'LinuxCrossArmTests', 'LinuxCrossMingwTests',
             'WindowsTests', 'DarwinTests']

    try:
        import pytest # noqa: F401
        pytest_args = []
        try:
            # Need pytest-xdist for `-n` arg
            import xdist # noqa: F401
            # Don't use pytest-xdist when running single unit tests since it wastes
            # time spawning a lot of processes to distribute tests to in that case.
            if not running_single_tests(sys.argv, cases):
                pytest_args += ['-n', 'auto']
        except ImportError:
            print('pytest-xdist not found, tests will not be distributed across CPU cores')
        # Let there be colors!
        if 'CI' in os.environ:
            pytest_args += ['--color=yes']
        pytest_args += ['unittests']
        pytest_args += convert_args(sys.argv[1:])
        # Always disable pytest-cov because we use a custom setup
        try:
            import pytest_cov # noqa: F401
            print('Disabling pytest-cov')
            pytest_args += ['-p' 'no:cov']
        except ImportError:
            pass
        return subprocess.run(python_command + ['-m', 'pytest'] + pytest_args).returncode
    except ImportError:
        print('pytest not found, using unittest instead')
    # Fallback to plain unittest.
    return unittest.main(defaultTest=cases, buffer=True)

if __name__ == '__main__':
    setup_vsenv()
    print('Meson build system', mesonbuild.coredata.version, 'Unit Tests')
    start = time.monotonic()
    try:
        raise SystemExit(main())
    finally:
        print('Total time: {:.3f} seconds'.format(time.monotonic() - start))
