#!/bin/env python3

import argparse
import fileinput
import os
import pathlib
import shutil
import subprocess


def main():
    parser = get_parser()
    args = parser.parse_args()

    if args.force_fresh_svunit_for_test:
        shutil.rmtree('svunit')
    if not pathlib.Path('svunit').is_dir():
        prepare_svunit_for_testing()

    run_tests(args)


def get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument('--force-fresh-svunit-for-test', action='store_true')
    parser.add_argument('--test')
    return parser


def prepare_svunit_for_testing():
    clone_stable_version_of_svunit()
    delete_problematic_directories_that_interfere_with_build()
    rename_source_files()
    update_package_to_include_renamed_source_files()
    update_package_name()
    update_build_script_to_use_renamed_source_files()
    update_source_files_to_use_new_package_name()
    update_bin_files_to_use_new_package_name()


def clone_stable_version_of_svunit():
    subprocess.check_call(['git', 'clone', 'https://github.com/svunit/svunit.git'])
    subprocess.check_call(['git', 'checkout', 'v3.36.0'], cwd='svunit')


def delete_problematic_directories_that_interfere_with_build():
    shutil.rmtree('svunit/svunit_base/util')
    shutil.rmtree('svunit/svunit_base/uvm-mock')
    shutil.rmtree('svunit/examples')
    shutil.rmtree('svunit/test')


def rename_source_files():
    source_root = pathlib.Path('svunit/svunit_base')
    for p in source_root.glob('*'):
        assert not p.is_dir() or p.name == 'junit-xml'  # TODO Handle junit-xml
    source_files = [p for p in source_root.glob('*') if p.is_file()]
    for f in source_files:
        assert f.name.startswith('svunit_')
    for f in source_files:
        f.rename(pathlib.Path(f.parent, f.name.replace('svunit_', 'svunit_stable_')))


def update_package_to_include_renamed_source_files():
    with fileinput.FileInput('svunit/svunit_base/svunit_stable_pkg.sv', inplace=True, backup='.bak') as file:
        for line in file:
            print(line.replace('`include "svunit_', '`include "svunit_stable_'), end='')


def update_package_name():
    with fileinput.FileInput('svunit/svunit_base/svunit_stable_pkg.sv', inplace=True, backup='.bak') as file:
        for line in file:
            print(line.replace('package svunit_', 'package svunit_stable_'), end='')


def update_build_script_to_use_renamed_source_files():
    with fileinput.FileInput('svunit/bin/buildSVUnit', inplace=True, backup='.bak') as file:
        for line in file:
            print(line.replace('svunit_base/svunit_', 'svunit_base/svunit_stable_'), end='')


def update_source_files_to_use_new_package_name():
    source_root = pathlib.Path('svunit/svunit_base')
    source_files = [p for p in source_root.glob('*') if p.is_file()]
    for f in source_files:
        with fileinput.FileInput(str(f), inplace=True, backup='.bak') as file:
            for line in file:
                print(line.replace('svunit_pkg::', 'svunit_stable_pkg::'), end='')


def update_bin_files_to_use_new_package_name():
    bin_root = pathlib.Path('svunit/bin')
    bin_files = [p for p in bin_root.glob('*') if p.is_file()]
    for f in bin_files:
        with fileinput.FileInput(str(f), inplace=True, backup='.bak') as file:
            for line in file:
                print(line.replace('svunit_pkg::', 'svunit_stable_pkg::'), end='')


def run_tests(args):
    run_env = os.environ.copy()
    run_env['SVUNIT_INSTALL'] = str(pathlib.Path('svunit').resolve())
    run_env['PATH'] = str(pathlib.Path('svunit').joinpath('bin').resolve()) + ':' + run_env['PATH']

    runSVUnit = ['svunit/bin/runSVUnit']

    if args.test:
        runSVUnit.extend(['--test', args.test])
    else:  # '--test' doesn't seem to play nice with '--directory' (#191)
        runSVUnit.extend([
            '--directory', '../src/test/sv',
            '--directory', '../src/testExperimental/sv',
            ])

    subprocess.check_call(runSVUnit, env=run_env)


main()
