#!/usr/bin/env python
# ===----------------------------------------------------------------------===##
#
# 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
#
# ===----------------------------------------------------------------------===##

"""
Runs an executable on a remote host.

This is meant to be used as an executor when running the C++ Standard Library
conformance test suite.
"""

import argparse
import os
import posixpath
import shlex
import subprocess
import sys
import tarfile
import tempfile

from shlex import quote as cmd_quote


def ssh(args, command):
    cmd = ["ssh", "-oBatchMode=yes"]
    if args.extra_ssh_args is not None:
        cmd.extend(shlex.split(args.extra_ssh_args))
    return cmd + [args.host, command]


def scp(args, src, dst):
    cmd = ["scp", "-q", "-oBatchMode=yes"]
    if args.extra_scp_args is not None:
        cmd.extend(shlex.split(args.extra_scp_args))
    return cmd + [src, "{}:{}".format(args.host, dst)]


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--host", type=str, required=True)
    parser.add_argument("--execdir", type=str, required=True)
    parser.add_argument("--tempdir", type=str, required=False, default="/tmp")
    parser.add_argument("--extra-ssh-args", type=str, required=False)
    parser.add_argument("--extra-scp-args", type=str, required=False)
    parser.add_argument("--codesign_identity", type=str, required=False, default=None)
    parser.add_argument("--env", type=str, nargs="*", required=False, default=[])
    parser.add_argument(
        "--prepend_env", type=str, nargs="*", required=False, default=[]
    )
    parser.add_argument("command", nargs=argparse.ONE_OR_MORE)
    args = parser.parse_args()
    commandLine = args.command

    # Create a temporary directory where the test will be run.
    # That is effectively the value of %T on the remote host.
    tmp = subprocess.check_output(
        ssh(args, "mktemp -d {}/libcxx.XXXXXXXXXX".format(args.tempdir)),
        universal_newlines=True,
    ).strip()

    # HACK:
    # If an argument is a file that ends in `.tmp.exe`, assume it is the name
    # of an executable generated by a test file. We call these test-executables
    # below. This allows us to do custom processing like codesigning test-executables
    # and changing their path when running on the remote host. It's also possible
    # for there to be no such executable, for example in the case of a .sh.cpp
    # test.
    isTestExe = lambda exe: exe.endswith(".tmp.exe") and os.path.exists(exe)
    pathOnRemote = lambda file: posixpath.join(tmp, os.path.basename(file))

    try:
        # Do any necessary codesigning of test-executables found in the command line.
        if args.codesign_identity:
            for exe in filter(isTestExe, commandLine):
                subprocess.check_call(
                    ["xcrun", "codesign", "-f", "-s", args.codesign_identity, exe],
                    env={},
                )

        # tar up the execution directory (which contains everything that's needed
        # to run the test), and copy the tarball over to the remote host.
        try:
            tmpTar = tempfile.NamedTemporaryFile(suffix=".tar", delete=False)
            with tarfile.open(fileobj=tmpTar, mode="w") as tarball:
                tarball.add(args.execdir, arcname=os.path.basename(args.execdir))

            # Make sure we close the file before we scp it, because accessing
            # the temporary file while still open doesn't work on Windows.
            tmpTar.close()
            remoteTarball = pathOnRemote(tmpTar.name)
            subprocess.check_call(scp(args, tmpTar.name, remoteTarball))
        finally:
            # Make sure we close the file in case an exception happens before
            # we've closed it above -- otherwise close() is idempotent.
            tmpTar.close()
            os.remove(tmpTar.name)

        # Untar the dependencies in the temporary directory and remove the tarball.
        remoteCommands = [
            "tar -xf {} -C {} --strip-components 1".format(remoteTarball, tmp),
            "rm {}".format(remoteTarball),
        ]

        # Make sure all test-executables in the remote command line have 'execute'
        # permissions on the remote host. The host that compiled the test-executable
        # might not have a notion of 'executable' permissions.
        for exe in map(pathOnRemote, filter(isTestExe, commandLine)):
            remoteCommands.append("chmod +x {}".format(exe))

        # Execute the command through SSH in the temporary directory, with the
        # correct environment. We tweak the command line to run it on the remote
        # host by transforming the path of test-executables to their path in the
        # temporary directory on the remote host.
        commandLine = (pathOnRemote(x) if isTestExe(x) else x for x in commandLine)
        remoteCommands.append("cd {}".format(tmp))

        if args.prepend_env:
            # We can't sensibly know the original value of the env vars
            # in order to prepend to them, so just overwrite these variables.
            args.env.extend(args.prepend_env)

        if args.env:
            env = list(map(cmd_quote, args.env))
            remoteCommands.append("export {}".format(" ".join(args.env)))
        remoteCommands.append(subprocess.list2cmdline(commandLine))

        # Finally, SSH to the remote host and execute all the commands.
        rc = subprocess.call(ssh(args, " && ".join(remoteCommands)))
        return rc

    finally:
        # Make sure the temporary directory is removed when we're done.
        subprocess.check_call(ssh(args, "rm -r {}".format(tmp)))


if __name__ == "__main__":
    exit(main())
