#!/usr/bin/env python3

"""This script verifies expression folding.
It compiles a source file with '-fdebug-dump-symbols'
and looks for parameter declarations to check
they have been folded as expected.
To check folding of an expression EXPR,
the fortran program passed to this script
must contain the following:

  logical, parameter :: test_x = <compare EXPR to expected value>

This script will test that all parameter
with a name starting with "test_"
have been folded to .true.
For instance, acos folding can be tested with:

  real(4), parameter :: res_acos = acos(0.5_4)
  real(4), parameter :: exp_acos = 1.047
  logical, parameter :: test_acos = abs(res_acos - exp_acos).LE.(0.001_4)

There are two kinds of failure:
  - test_x is folded to .false..
    This means the expression was folded
    but the value is not as expected.
  - test_x is not folded (it is neither .true. nor .false.).
    This means the compiler could not fold the expression.

Parameters:
    sys.argv[1]: a source file with contains the input and expected output
    sys.argv[2]: the Flang frontend driver
    sys.argv[3:]: Optional arguments to the Flang frontend driver"""

import os
import sys
import tempfile
import re
import subprocess

from difflib import unified_diff
from pathlib import Path


def check_args(args):
    """Verifies that the number is arguments passed is correct."""
    if len(args) < 3:
        print(f"Usage: {args[0]} <fortran-source> <flang-command>")
        sys.exit(1)


def set_source(source):
    """Sets the path to the source files."""
    if not Path(source).is_file():
        print(f"File not found: {src}")
        sys.exit(1)
    return Path(source)


def set_executable(exe):
    """Sets the path to the Flang frontend driver."""
    if not Path(exe).is_file():
        print(f"Flang was not found: {exe}")
        sys.exit(1)
    return str(Path(exe))


check_args(sys.argv)
cwd = os.getcwd()
srcdir = set_source(sys.argv[1]).resolve()
with open(srcdir, "r", encoding="utf-8") as f:
    src = f.readlines()
src1 = ""
src2 = ""
src3 = ""
src4 = ""
messages = ""
actual_warnings = ""
expected_warnings = ""
warning_diffs = ""

flang_fc1 = set_executable(sys.argv[2])
flang_fc1_args = sys.argv[3:]
flang_fc1_options = ""
LIBPGMATH = os.getenv("LIBPGMATH")
if LIBPGMATH:
    flang_fc1_options = ["-fdebug-dump-symbols", "-DTEST_LIBPGMATH"]
    print("Assuming libpgmath support")
else:
    flang_fc1_options = ["-fdebug-dump-symbols"]
    print("Not assuming libpgmath support")

cmd = [flang_fc1, *flang_fc1_args, *flang_fc1_options, str(srcdir)]
with tempfile.TemporaryDirectory() as tmpdir:
    proc = subprocess.run(
        cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=True,
        universal_newlines=True,
        cwd=tmpdir,
    )
    src1 = proc.stdout
    messages = proc.stderr

for line in src1.split("\n"):
    m = re.search(r"(\w*)(?=, PARAMETER).*init:(.*)", line)
    if m:
        src2 += f"{m.group(1)} {m.group(2)}\n"

for line in src2.split("\n"):
    m = re.match(r"test_*", line)
    if m:
        src3 += f"{m.string}\n"

for passed_results, line in enumerate(src3.split("\n")):
    m = re.search(r"\.false\._.$", line)
    if m:
        src4 += f"{line}\n"

for line in messages.split("\n"):
    m = re.search(r"[^:]*:(\d*):\d*: (.*)", line)
    if m:
        actual_warnings += f"{m.group(1)}: {m.group(2)}\n"

passed_warnings = 0
warnings = []
for i, line in enumerate(src, 1):
    m = re.search(r"(?:!WARN:)(.*)", line)
    if m:
        warnings.append(m.group(1))
        continue
    if warnings:
        for x in warnings:
            passed_warnings += 1
            expected_warnings += f"{i}:{x}\n"
        warnings = []

for line in unified_diff(
    actual_warnings.split("\n"), expected_warnings.split("\n"), n=0
):
    line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)
    line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line)
    warning_diffs += line

if src4 or warning_diffs:
    print("Folding test failed:")
    # Prints failed tests, including parameters with the same
    # suffix so that more information can be obtained by declaring
    # expected_x and result_x
    if src4:
        for line in src4.split("\n"):
            m = re.match(r"test_(\w+)", line)
            if m:
                for line in src2.split("\n"):
                    if m.group(1) in line:
                        print(line)
    if warning_diffs:
        print(warning_diffs)
    print()
    print("FAIL")
    sys.exit(1)
else:
    print()
    print(f"All {passed_results+passed_warnings} tests passed")
    print("PASS")
