# This file is distributed under the University of Illinois Open Source License.
# See LICENSE.TXT for details.
# -*- 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) )
