#!/usr/bin/env python3

"""
Various checks for certain C++ style rules that we choose for BornAgain,
in addition to the rules imposed by clang-format.

Copyright Forschungszentrum Jülich GmbH 2025.
License:  Public Domain
"""

import check_utils as cu
import os, re, sys

####################################################################################################
# checks
####################################################################################################

def check_parallel_includes(stem, th, tc, errs):
    '''
    Detects if the same file is included in foo.h and foo.cpp.
    '''

    included_by_h = []
    for m in re.finditer(r'#include ["<](.*?)[">]', th):
        included_by_h.append(m.group(1))

    if len(included_by_h) == 0:
        return

    alternatives = '|'.join(included_by_h)
    if not re.search(r'#include ["<](' + alternatives + r')[">]', tc):
        return

    # found error, now generate informative message
    duplicates = []
    for inc in included_by_h:
        if re.search(r'#include ["<](' + inc + r')[">]', tc):
            duplicates.append(inc)

    errs.append(f"{stem}.cpp and the corresponding .h file both include "
                + ', '.join(duplicates))


####################################################################################################
# main
####################################################################################################

if __name__ == "__main__":

    assert len(sys.argv) == 1, "Check script must be called without arguments"

    # tests on file pairs:
    errs = []
    for fn in cu.all_files():
        stem, suffix = cu.split_fname(fn)
        if suffix != 'cpp':
            continue
        fh = stem+'.h'
        fc = fn
        if not os.path.exists(fh):
            continue
        with open(fh, 'r') as fd:
            th = fd.read()
        with open(fc, 'r') as fd:
            tc = fd.read()
        check_parallel_includes(stem, th, tc, errs)

    if len(errs) > 0:
        print("Found error(s):")
        for err in errs:
            print("- " + err)
        sys.exit(1)

    sys.exit(0)
