# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# -*- Python -*-

import lit

# Configuration file for the 'lit' test runner.

# name: The name of this test suite.
config.name = 'SN C++ IA64 ABI Tests'

# 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(execute_external = True)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.c', '.cpp']

###

# Discover the 'clang' and 'clangcc' to use.

import os
import shutil

def copyFile(srcfile,dstfile):
    try:
        shutil.copyfile(srcfile, dstfile)
    except:
        sfp = open(srcfile, "r")
        src = sfp.read();
        dfp = open(dstfile, "w")
        dfp.write(src)
        dfp.close()
        sfp.close()    
    return

def generateTests():
    config = lit_config.params["test_params"]
    
    if "skip_list" not in config or len(config["skip_list"]) == 0:
        skip_list = []
    else:
        skip_list = [os.path.normpath(tmp) for tmp in sorted(config["skip_list"])]
    
    for root, dirs, files in os.walk("test"):
        for filename in files:
            (file_noext, ext) = os.path.splitext(filename)
            new_ext = ""
            if ext == ".x":
                new_ext = ".c"
            elif ext == ".xpp":
                new_ext = ".cpp"
            else:
                # skip this file
                continue
            
            # Generate the full new/old filenames
            srcfile = os.path.join(root, filename)
            dstfile = os.path.join(root, file_noext + new_ext)

            # Algorithm for creating the files more optimally:
            # 
            # Target file Exists:
            #  - Size is same as original
            #    - File is NOT in skip list
            #      => No action needed
            #    - File is in skip list
            #      => Append skip lines to file
            #  - Size is different from original
            #    - File is NOT in skip list
            #      => Delete file and copy over original file
            #    - File is in skip list
            #      => No action needed
            #
            # Target file does not exist:
            #  => Copy over file and add skip line as necessary

            # Copy foo.xpp => foo.cpp if necessary
            if "force_copy" in config and int(config["force_copy"]) == 1:
                # Force the copy by deleting the file
                os.remove(dstfile)
            if os.path.isfile(dstfile):
                src_size = os.path.getsize(srcfile)
                dst_size = os.path.getsize(dstfile)
                if src_size != dst_size:
                    if os.path.splitext(srcfile)[0] in skip_list:
                        # File is already marked as expected fail, so no further action needed
                        continue
                    else:
                        # Delete the file
                        os.remove(dstfile)
                        # Copy the original file over
                        copyFile(srcfile, dstfile)
            else:
                # Target file does not exist, so copy over the original
                copyFile(srcfile, dstfile)

            # At this point we have the original file copied over, detect whether we need
            # to mark it as an expected failure
            if os.path.splitext(srcfile)[0] in skip_list:
                # If a file is in the skip list, mark it as expected failure
                with open(dstfile, "a") as skipfile:
                    skipfile.write("// XFAIL: *\n")
    
    return

def determinePlatform():
    tspec = lit_config.params["test_params"]

    platform = tspec["Platform"]
    config.environment['SN_PLATFORM'] = platform
    
    platform_defs = {}

    platform_defs['common'] = os.path.join('%s' % os.path.dirname(os.path.realpath(__file__)), "common")
    platform_defs['platform'] = platform
    platform_defs['c_compiler'] = tspec["c_compiler"]
    platform_defs['cxx_compiler'] = tspec["cxx_compiler"]
    platform_defs['runtool'] = tspec["runtool"]
    platform_defs['bindump'] = tspec["bindump"]
    platform_defs['cxx_rtti'] = tspec["cxx_rtti"]
    platform_defs['cxx_exceptions'] = tspec["cxx_exceptions"]
    if 'linker' in tspec:
      platform_defs['linker'] = tspec["linker"]
    else:
      platform_defs['linker'] = tspec["c_compiler"]
    if 'checker' in tspec:
      platform_defs['checker'] = tspec["checker"]
    else:
      platform_defs['checker'] = "grep"
    platform_defs['prefixes'] = '--check-prefix=CHECK ' + tspec["prefixes"]
    platform_defs['cxx_11'] = tspec["cxx_cpp11"]

    hfp = open("selector.h", "w")

    if 'compiler_flags' in tspec:
        platform_defs['c_compiler'] = platform_defs['c_compiler'] + ' ' + tspec['compiler_flags']
        platform_defs['cxx_compiler'] = platform_defs['cxx_compiler'] + ' ' + tspec['compiler_flags']
    if 'linker_flags' in tspec:
        platform_defs['linker'] = platform_defs['linker'] + ' ' + tspec['linker_flags']

 # possible values are LP64-x86 ILP32-x86

    im = tspec["Mode"]
    if (im == "LP64-x86") :
      # 64 bit x86 clang3.4 mode.
      hfp.write("#define ABISELECT(a,b) a // LP64 x86\n")
    elif (im == "ILP32-x86"):
      # 32 bit x86, Dual align
      hfp.write("#define ABISELECT(a,b) b // LP64 x86\n")
    #  #sys.exit(1)
    else:
      print "ERROR: Invalid combination of config options. tspec= " , tspec
      sys.exit(1)
    hfp.close()

    return platform_defs

# Determine which toolset to use
tools = determinePlatform()
generateTests()
if not lit_config.quiet:
    lit_config.note('using toolset:')
    for key, value in tools.items():
        lit_config.note('\t%s => %s' % (key, value))
for key, value in tools.items():
    config.substitutions.append( (key, value) )
