# 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"] = "--allow-unused-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(f"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))
