import os
import json
import shutil
import subprocess
from pathlib import Path
import distill_coverage_results

env = dict(os.environ)
env['RUSTFLAGS'] = "-C instrument-coverage"
env['LLVM_PROFILE_FILE'] = "your_name-%p-%m.profraw"

coverage_file = 'coverage.json'

def get_profile_files(the_dir):
    return list(filter(lambda x: x.endswith('.profraw'), os.listdir(the_dir)))

def delete_coverage_files():
    for the_file in get_profile_files('.'):
        if the_file.endswith('.profraw'):
            os.unlink(the_file)

    try:
        os.unlink(coverage_file)
    except:
        pass

def run_coverage_test():
    subprocess.check_call(['cargo','test'],env=env)

def is_my_code(desc):
    for path in ['.cargo','library/std','src/py','src/classic/bins']:
        if path in desc['name']:
            return False

    return True

def collect_coverage():
    profile_files = get_profile_files('.')
    args = ['grcov','--binary-path','target/debug','--output-type','covdir','--output-path',coverage_file] + profile_files
    subprocess.check_call(args)
    result = distill_coverage_results.CoverageResult()

    infile = json.loads(open(coverage_file).read())
    for root in infile['children'].keys():
        distill_coverage_results.distill_coverage(result, Path(root), infile['children'][root])
    return list(filter(is_my_code, result.show_result()))

if __name__ == '__main__':
    import argparse
    import sys

    parser = argparse.ArgumentParser()
    parser.add_argument('--require-percent', help="required percentage to succeed", default=None)
    args = parser.parse_args()

    delete_coverage_files()
    run_coverage_test()
    result = collect_coverage()
    print(json.dumps(result, indent=4))

    if args.require_percent is not None:
        required_percentage = int(args.require_percent)
        has_required_pct = True

        for file in result:
            have_pct = int(file['coveragePercent'])
            if have_pct < required_percentage:
                print(f"{file['name']} lacks required coverage have {have_pct} want {required_percentage}")
                has_required_pct = False

        if not has_required_pct:
            sys.exit(1)

