#!/usr/bin/python3

import sys


def main():

    if len (sys.argv) < 3:
        print ("Missing args: <logfile to check> <expected num logs>")
        exit(2)

    log_file = sys.argv[1]
    n_assert = int(sys.argv[2])

    # line count
    n_cpp=0
    n_py=0
    n=0

    # cache string positions (for speed)
    cpp_s=False; cpp_s1=0; cpp_s2=0; cpp_s3=0
    py_s=False; py_s1=0; py_s2=0; py_s3=0


    # expectations
    exp_cpp = [0,0,0]  # 3 threads
    exp_py = 0

    # problems
    n_cpp_badseq = 0
    n_py_badseq = 0
    n_strange = 0

    with open(log_file, "r") as f:
        for line in f:

            # we rely on uniform messages, and cache string positions
            if not cpp_s and "cpplib" in line:
                cpp_s1 = line.find("cpplib")
                cpp_s2 = cpp_s1 + 6
                cpp_s3 = line.find("Message=")+8
                cpp_s = True
            if not py_s and "pyapp" in line:
                py_s1 = line.find("pyapp")
                py_s2 = py_s1 + 5
                py_s3 = line.find("write:", py_s2)+6
                py_s = True

            if line[cpp_s1:cpp_s2] == "cpplib":
                n_cpp += 1
                thr = int(line[-3:-2])
                num = int(line[cpp_s3: line.find(" ",cpp_s3) ] )
                if num != exp_cpp[thr]:
                    n_cpp_badseq += 1
                    print("cpp badseq:",exp_cpp[thr],num)
                    exp_cpp[thr] = num # reset to prevent errors from piling up
                    # one could make some further distinction whether the found
                    # num is smaller or larger than the expectation.                
                exp_cpp[thr] += 1

            elif line[py_s1:py_s2] == "pyapp":
                n_py += 1
                num = int(line[py_s3:])
                if num != exp_py:
                    n_py_badseq += 1
                    print("py badseq:",exp_py,num)
                    exp_py = num # reset to prevent errors from piling up
                    # one could make some further distinction whether the found
                    # num is smaller or larger than the expectation.                
                exp_py += 1

                # debug
                #if n>50 and n<60: print (num)

            else:
                n_strange += 1

            n=n+1

    print (f"done reading {n} lines. Found {n_py} py lines, {n_cpp} cpp lines, {n_strange} unrecognised")
    print (f"exp_cpp {exp_cpp}, exp_py {exp_py}")
    print (f"badseq:  cpp: {n_cpp_badseq}, py: {n_py_badseq}")

    rc = 0
    if n != n_assert: rc = 3 # logs were lost (or duplicated)
    elif n_cpp_badseq + n_py_badseq != 0: rc = 4 # logs have wrong order

    print ("jointlog-check rc", rc)
    return rc

if __name__ == '__main__':
    sys.exit (main())
