#!/usr/bin/python

import subprocess

"""
`pytest --collect-test` output format is something like this:

<Module 'test_integration/test_replication_layouts.py'>
  <Class 'TestCompleteTopologyWithCAKRA'>
    <Instance '()'>
      <Function 'test_complete_topology_with_ca_kra'>

Prerequisites of this script:

Make sure you have dependencies for fastcheck - same dependencies are required
 for collecting tests.
   https://www.freeipa.org/page/Testing#Fast_test

$ sudo dnf builddep -b -D "with_python3 1" -D "with_wheels 1" -D "with_lint 1" --spec freeipa.spec.in --allowerasing
$ ./autogen.sh

"""

NIGHTLY_IN = "ipatests/prci_definitions/nightly_master.yaml"
GATING_IN = "ipatests/prci_definitions/gating.yaml"

def get_name(text):
    start = text.index('\'')
    end = text.rindex('\'')
    name = text[start+1:end]
    return name

def parse_tests(pytests_out, tests):
    module = ""
    c_name = ""

    for line in pytests_out.split('\n'):
        if "<Module" in line:
            m_name = get_name(line)
            module = m_name
            continue

        if "<Class" in line:
            c_name = get_name(line)
            continue

        if "<Function" in line:
            f_name = get_name(line)
            if line.startswith('      '):
                tests.append((module, c_name, f_name))
            else:
                tests.append((module, None, f_name))
            continue
        continue

def get_tests(file_in):
    tests = []
    parse_tests(file_in, tests)
    str_tests = {
        "{}::{}::{}".format(t[0], t[1], t[2])  for t in tests
    }
    return tests, str_tests

def print_tests(str_tests, title):
    print("")
    print(title)
    l = list(str_tests)
    l.sort()
    for t in l:
        print(t)

def read_tests(cmd):
    return subprocess.Popen(cmd, shell=True,
        stdout=subprocess.PIPE).stdout.read()

def collect_tests():
    all_tests_cmd = "pytest-3 --collect-only ipatests/test_integration/"
    prci_cmd_tmpl = ("cat {} | grep test_integration |"
                     " awk '{{ print \"ipatests/\" $2}}'"
                     " | xargs pytest-3.6 --collect-only")

    all_tests = read_tests(all_tests_cmd)
    gating_tests = read_tests(prci_cmd_tmpl.format(GATING_IN))
    nighlty_tests = read_tests(prci_cmd_tmpl.format(NIGHTLY_IN))
    return all_tests, gating_tests, nighlty_tests

def compare_test(all_integration, nightlies, gating):
    all_in_ci = nightlies.union(gating)
    missing = all_integration - all_in_ci
    redundant = all_in_ci - all_integration
    nighly_gating_overlap = gating & nightlies

    print_tests(nightlies, "Nightly Integration Tests:")
    print_tests(gating, "Gating Tests")
    print_tests(all_integration, "All Integration tests:")
    print_tests(nighly_gating_overlap, "Nightly and Gating overlap:")

    if missing:
        print_tests(missing, "Tests not in CI")
    else:
        print ("\nAll tests are defined in CI \\o/\n")

    if redundant:
        print_tests(redundant, "Miraculously added tests:")

def main():
    all_def, gating_def, nightly_def = collect_tests()
    all_tests, str_all = get_tests(all_def)
    nightly_tests, str_nightlies = get_tests(gating_def)
    gating_tests, str_gating = get_tests(nightly_def)
    compare_test(str_all, str_nightlies, str_gating)

if __name__ == "__main__":
    main()
