import os

import lit.formats
import lit.util

# python 2.7 backwards compatibility
try:
    from shlex import quote as shell_quote
except ImportError:
    from pipes import quote as shell_quote


def add_update_script_substition(name, python_exe=config.python_executable,
                                 extra_args=''):
    assert name.startswith('%')
    script_path = os.path.join(config.llvm_src_root, 'utils', name[1:] + '.py')
    assert os.path.isfile(script_path)
    config.substitutions.append(
        (name, "'%s' %s %s" % (python_exe, script_path, extra_args)))


config.test_format = lit.formats.ShTest(execute_external=False)
config.suffixes = ['.test']

llc_path = os.path.join(config.llvm_tools_dir, 'llc')
if os.path.isfile(llc_path):
    config.available_features.add('llc-binary')
    llc_arg = '--llc-binary ' + shell_quote(llc_path)
    add_update_script_substition('%update_llc_test_checks', extra_args=llc_arg)
    add_update_script_substition('%update_mir_test_checks', extra_args=llc_arg)

opt_path = os.path.join(config.llvm_tools_dir, 'opt')
if os.path.isfile(opt_path):
    config.available_features.add('opt-binary')
    opt_arg = '--opt-binary ' + shell_quote(opt_path)
    add_update_script_substition('%update_test_checks', extra_args=opt_arg)
    add_update_script_substition('%update_analyze_test_checks',
                                 extra_args=opt_arg)

llvm_mca_path = os.path.join(config.llvm_tools_dir, 'llvm-mca')
if os.path.isfile(llvm_mca_path):
    config.available_features.add('llvm-mca-binary')
    mca_arg = '--llvm-mca-binary ' + shell_quote(llvm_mca_path)
    add_update_script_substition('%update_test_checks', extra_args=mca_arg)
