#!/usr/bin/env vpython3
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import os
import stat
import sys

sys.path.append(
    os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir,
                 'build'))
import action_helpers


def _parse_args(args):
    description = 'Generator of bash scripts that can invoke the Python ' \
                  'library for running Rust unit tests with support for ' \
                  'Chromium test filters, sharding, and test output.'
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument('--script-path',
                        dest='script_path',
                        help='Where to write the bash script.',
                        metavar='FILEPATH',
                        required=True)
    parser.add_argument('--exe-dir',
                        dest='exe_dir',
                        help='Directory where the wrapped executables are',
                        metavar='PATH',
                        required=True)
    parser.add_argument('--rust-test-executables',
                        dest='rust_test_executables',
                        help='File listing one or more executables to wrap. ' \
                             '(basenames - no .exe extension or directory)',
                        metavar='FILEPATH',
                        required=True)
    parser.add_argument('--make-bat',
                        action='store_true',
                        help='Generate a .bat file instead of a bash script')
    return parser.parse_args(args=args)


def _find_test_executables(args):
    exes = set()
    input_filepath = args.rust_test_executables
    with open(input_filepath) as f:
        for line in f:
            exe_name = line.strip()
            # Append ".exe" extension when *targeting* Windows, not when this
            # script is running on windows. We do that by using `args.make_bat`
            # as a signal.
            if exe_name in exes:
                raise ValueError(
                    f'Duplicate entry "{exe_name}" in {input_filepath}')
            if args.make_bat:
                suffix = ".exe"
            else:
                suffix = ""
            exes.add(f'{exe_name}{suffix}')
    if not exes:
        raise ValueError(f'Unexpectedly empty file: {input_filepath}')
    exes = sorted(exes)  # For stable results in unit tests.
    return exes


def _validate_if_test_executables_exist(exes):
    for exe in exes:
        if not os.path.isfile(exe):
            raise ValueError(f'File not found: {exe}')


def _generate_script(args, should_validate_if_exes_exist=True):
    THIS_DIR = os.path.abspath(os.path.dirname(__file__))
    GEN_SCRIPT_DIR = os.path.dirname(args.script_path)

    # Path from the .bat or bash script to the test exes.
    exe_dir = os.path.relpath(args.exe_dir, start=GEN_SCRIPT_DIR)
    exe_dir = os.path.normpath(exe_dir)

    # Path from the .bat or bash script to the python main.
    main_dir = os.path.relpath(THIS_DIR, start=GEN_SCRIPT_DIR)
    main_dir = os.path.normpath(main_dir)

    exes = _find_test_executables(args)
    if should_validate_if_exes_exist:
        _validate_if_test_executables_exist(exes)

    if args.make_bat:
        res = '@echo off\n'
        res += f'vpython3 "%~dp0\\{main_dir}\\rust_main_program.py" ^\n'
        for exe in exes:
            res += f'    "--rust-test-executable=%~dp0\\{exe_dir}\\{exe}" ^\n'
        res += '    %*'
    else:
        res = '#!/bin/bash\n'
        res += (f'env vpython3 '
                f'"$(dirname $0)/{main_dir}/rust_main_program.py" \\\n')
        for exe in exes:
            res += (
                f'    '
                f'"--rust-test-executable=$(dirname $0)/{exe_dir}/{exe}" \\\n')
        res += '    "$@"'
    return res


def _main():
    args = _parse_args(sys.argv[1:])

    # atomic_output will ensure we only write to the file on disk if what we
    # give to write() is different than what's currently on disk.
    with action_helpers.atomic_output(args.script_path) as f:
        f.write(_generate_script(args).encode())

    # chmod a+x
    st = os.stat(args.script_path)
    if (not st.st_mode & stat.S_IXUSR) or (not st.st_mode & stat.S_IXGRP) or \
       (not st.st_mode & stat.S_IXOTH):
        os.chmod(args.script_path,
                 st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)


if __name__ == '__main__':
    _main()
