# -*- Python -*-

import os
import platform
import re
import subprocess
import sys

import lit.formats
import lit.util

from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst
from lit.llvm.subst import FindTool

# Configuration file for the 'lit' test runner.

# name: The name of this test suite.
config.name = 'Flang'

# testFormat: The test format to use to interpret tests.
#
# For now we require '&&' between commands, until they get globally killed and
# the test runner updated.
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.c', '.cpp', '.f', '.F', '.ff', '.FOR', '.for', '.f77', '.f90', '.F90',
                   '.ff90', '.f95', '.F95', '.ff95', '.fpp', '.FPP', '.cuf'
                   '.CUF', '.f18', '.F18', '.fir', '.f03', '.F03', '.f08', '.F08']

config.substitutions.append(('%PATH%', config.environment['PATH']))

llvm_config.use_default_substitutions()

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']

# If the new Flang driver is enabled, add the corresponding feature to
# config. Otherwise, exclude the corresponding test directory.
if config.include_flang_new_driver_test:
  config.available_features.add('new-flang-driver')
else:
  config.excludes.append('Flang-Driver')
  config.excludes.append('Frontend')

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# test_exec_root: The root path where tests should be run.
config.test_exec_root = os.path.join(config.flang_obj_root, 'test')

# Tweak the PATH to include the tools dir.
llvm_config.with_environment('PATH', config.flang_tools_dir, append_path=True)
llvm_config.with_environment('PATH', config.llvm_tools_dir, append_path=True)

if config.flang_standalone_build:
    # For builds with FIR, set path for tco and enable related tests
    if config.flang_llvm_tools_dir != "":
        config.available_features.add('fir')
        if config.llvm_tools_dir != config.flang_llvm_tools_dir:
            llvm_config.with_environment('PATH', config.flang_llvm_tools_dir, append_path=True)

# For each occurrence of a flang tool name, replace it with the full path to
# the build directory holding that tool.
tools = [
  ToolSubst('%f18', command=FindTool('f18'),
    extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir],
    unresolved='fatal')
]

if config.include_flang_new_driver_test:
   tools.append(ToolSubst('%flang-new', command=FindTool('flang-new'), unresolved='fatal'))
   tools.append(ToolSubst('%flang', command=FindTool('flang-new'), unresolved='fatal'))
else:
   tools.append(ToolSubst('%flang', command=FindTool('f18'),
    extra_args=["-intrinsic-module-directory "+config.flang_intrinsic_modules_dir],
    unresolved='fatal'))

if config.flang_standalone_build:
    llvm_config.add_tool_substitutions(tools, [config.flang_llvm_tools_dir])
else:
    llvm_config.add_tool_substitutions(tools, config.llvm_tools_dir)

# Enable libpgmath testing
result = lit_config.params.get("LIBPGMATH")
if result:
    config.environment["LIBPGMATH"] = True
