#!/usr/bin/env python3
#
# Configure environment and run group of tests in it.
#
# Copyright (c) 2020-2021 Virtuozzo International GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import sys
import argparse
import shutil
from pathlib import Path

from findtests import TestFinder
from testenv import TestEnv
from testrunner import TestRunner


def make_argparser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(description="Test run options")

    p.add_argument('-n', '--dry-run', action='store_true',
                   help='show me, do not run tests')
    p.add_argument('-j', dest='jobs', type=int, default=1,
                   help='run tests in multiple parallel jobs')

    p.add_argument('-d', dest='debug', action='store_true', help='debug')
    p.add_argument('-p', dest='print', action='store_true',
                   help='redirects qemu\'s stdout and stderr to '
                        'the test output')
    p.add_argument('-gdb', action='store_true',
                   help="start gdbserver with $GDB_OPTIONS options "
                        "('localhost:12345' if $GDB_OPTIONS is empty)")
    p.add_argument('-valgrind', action='store_true',
                   help='use valgrind, sets VALGRIND_QEMU environment '
                        'variable')

    p.add_argument('-misalign', action='store_true',
                   help='misalign memory allocations')
    p.add_argument('--color', choices=['on', 'off', 'auto'],
                   default='auto', help="use terminal colors. The default "
                   "'auto' value means use colors if terminal stdout detected")
    p.add_argument('-tap', action='store_true',
                   help='produce TAP output')

    g_env = p.add_argument_group('test environment options')
    mg = g_env.add_mutually_exclusive_group()
    # We don't set default for cachemode, as we need to distinguish default
    # from user input later.
    mg.add_argument('-nocache', dest='cachemode', action='store_const',
                    const='none', help='set cache mode "none" (O_DIRECT), '
                    'sets CACHEMODE environment variable')
    mg.add_argument('-c', dest='cachemode',
                    help='sets CACHEMODE environment variable')

    g_env.add_argument('-i', dest='aiomode', default='threads',
                       help='sets AIOMODE environment variable')

    p.set_defaults(imgfmt='raw', imgproto='file')

    format_list = ['raw', 'bochs', 'cloop', 'parallels', 'qcow', 'qcow2',
                   'qed', 'vdi', 'vpc', 'vhdx', 'vmdk', 'luks', 'dmg']
    g_fmt = p.add_argument_group(
        '  image format options',
        'The following options set the IMGFMT environment variable. '
        'At most one choice is allowed, default is "raw"')
    mg = g_fmt.add_mutually_exclusive_group()
    for fmt in format_list:
        mg.add_argument('-' + fmt, dest='imgfmt', action='store_const',
                        const=fmt, help=f'test {fmt}')

    protocol_list = ['file', 'rbd', 'nbd', 'ssh', 'nfs', 'fuse']
    g_prt = p.add_argument_group(
        '  image protocol options',
        'The following options set the IMGPROTO environment variable. '
        'At most one choice is allowed, default is "file"')
    mg = g_prt.add_mutually_exclusive_group()
    for prt in protocol_list:
        mg.add_argument('-' + prt, dest='imgproto', action='store_const',
                        const=prt, help=f'test {prt}')

    g_bash = p.add_argument_group('bash tests options',
                                  'The following options are ignored by '
                                  'python tests.')
    # TODO: make support for the following options in iotests.py
    g_bash.add_argument('-o', dest='imgopts',
                        help='options to pass to qemu-img create/convert, '
                        'sets IMGOPTS environment variable')

    g_sel = p.add_argument_group('test selecting options',
                                 'The following options specify test set '
                                 'to run.')
    g_sel.add_argument('-g', '--groups', metavar='group1,...',
                       help='include tests from these groups')
    g_sel.add_argument('-x', '--exclude-groups', metavar='group1,...',
                       help='exclude tests from these groups')
    g_sel.add_argument('--start-from', metavar='TEST',
                       help='Start from specified test: make sorted sequence '
                       'of tests as usual and then drop tests from the first '
                       'one to TEST (not inclusive). This may be used to '
                       'rerun failed ./check command, starting from the '
                       'middle of the process.')
    g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
                       help='tests to run, or "--" followed by a command')

    return p


if __name__ == '__main__':
    args = make_argparser().parse_args()

    env = TestEnv(imgfmt=args.imgfmt, imgproto=args.imgproto,
                  aiomode=args.aiomode, cachemode=args.cachemode,
                  imgopts=args.imgopts, misalign=args.misalign,
                  debug=args.debug, valgrind=args.valgrind,
                  gdb=args.gdb, qprint=args.print)

    if len(sys.argv) > 1 and sys.argv[-len(args.tests)-1] == '--':
        if not args.tests:
            sys.exit("missing command after '--'")
        cmd = args.tests
        env.print_env()
        exec_pathstr = shutil.which(cmd[0])
        if exec_pathstr is None:
            sys.exit('command not found: ' + cmd[0])
        exec_path = Path(exec_pathstr).resolve()
        cmd[0] = str(exec_path)
        full_env = env.prepare_subprocess(cmd)
        os.chdir(exec_path.parent)
        os.execve(cmd[0], cmd, full_env)

    testfinder = TestFinder(test_dir=env.source_iotests)

    groups = args.groups.split(',') if args.groups else None
    x_groups = args.exclude_groups.split(',') if args.exclude_groups else None

    group_local = os.path.join(env.source_iotests, 'group.local')
    if os.path.isfile(group_local):
        try:
            testfinder.add_group_file(group_local)
        except ValueError as e:
            sys.exit(f"Failed to parse group file '{group_local}': {e}")

    try:
        tests = testfinder.find_tests(groups=groups, exclude_groups=x_groups,
                                      tests=args.tests,
                                      start_from=args.start_from)
        if not tests:
            raise ValueError('No tests selected')
    except ValueError as e:
        sys.exit(str(e))

    if args.dry_run:
        print('\n'.join(tests))
    else:
        with TestRunner(env, tap=args.tap,
                        color=args.color) as tr:
            paths = [os.path.join(env.source_iotests, t) for t in tests]
            ok = tr.run_tests(paths, args.jobs)
            if not ok:
                sys.exit(1)
