#!/usr/bin/env python
# utils/rth - Resilience test helper
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

from __future__ import print_function

import argparse
import os
import pipes
import shlex
import shutil
import subprocess
import sys

VERBOSE = True


def verbose_print_command(command):
    if VERBOSE:
        print(" ".join(pipes.quote(c) for c in command))
        sys.stdout.flush()


class ResilienceTest(object):

    def __init__(self, target_build_swift, target_run, tmp_dir, test_dir,
                 test_src, additional_compile_flags_library,
                 no_backward_deployment):
        self.target_build_swift = shlex.split(target_build_swift)
        self.target_run = shlex.split(target_run)
        self.tmp_dir = tmp_dir
        self.test_dir = test_dir
        self.test_src = test_src
        self.additional_compile_flags_library = \
            shlex.split(additional_compile_flags_library)

        self.before_dir = os.path.join(self.tmp_dir, 'before')
        self.after_dir = os.path.join(self.tmp_dir, 'after')
        self.config_dir_map = {'BEFORE': self.before_dir,
                               'AFTER': self.after_dir}

        self.lib_src_name = os.path.basename(self.test_src)[5:]
        self.lib_obj_name = self.lib_src_name[:-6] + '.o'
        self.lib_src = os.path.join(self.test_dir, 'Inputs', self.lib_src_name)

        self.no_backward_deployment = no_backward_deployment

    def run(self):
        self.set_up()
        self.compile_library()
        self.compile_main()
        self.link()
        self.execute()
        return 0

    def set_up(self):
        shutil.rmtree(self.tmp_dir, ignore_errors=True)
        os.makedirs(self.after_dir)
        os.makedirs(self.before_dir)

    def compile_library(self):
        for config in self.config_dir_map:
            for emit_flag in ['-emit-library', '-emit-module']:
                output_obj = os.path.join(self.config_dir_map[config],
                                          self.lib_obj_name)
                compiler_flags = [emit_flag, '-Xfrontend',
                                  '-enable-resilience', '-D', config, '-c',
                                  self.lib_src, '-o', output_obj]
                command = self.target_build_swift + \
                    self.additional_compile_flags_library + compiler_flags
                verbose_print_command(command)
                returncode = subprocess.call(command)
                assert returncode == 0, str(command)

    def compile_main(self):
        for config in self.config_dir_map:
            output_obj = os.path.join(self.config_dir_map[config], 'main.o')
            compiler_flags = ['-D', config, '-c', self.test_src, '-I',
                              self.config_dir_map[config], '-o', output_obj]
            command = self.target_build_swift + compiler_flags
            verbose_print_command(command)
            returncode = subprocess.call(command)
            assert returncode == 0, str(command)

    def configs(self):
        for config1 in self.config_dir_map:
            for config2 in self.config_dir_map:
                # --no-backward-deployment skips testing a new application
                # linked against an old library.
                if config1 == "BEFORE" and \
                   config2 == "AFTER" and \
                   self.no_backward_deployment:
                    continue

                yield (config1, config2)

    def link(self):
        for config1, config2 in self.configs():
            config1_lower = config1.lower()
            config2_lower = config2.lower()
            output_obj = os.path.join(self.tmp_dir,
                                      config1_lower + '_' + config2_lower)
            compiler_flags = [
                os.path.join(self.config_dir_map[config1],
                             self.lib_obj_name),
                os.path.join(self.config_dir_map[config2],
                             'main.o'),
                '-o', output_obj
            ]
            command = self.target_build_swift + compiler_flags
            verbose_print_command(command)
            returncode = subprocess.call(command)
            assert returncode == 0, str(command)

    def execute(self):
        for config1, config2 in self.configs():
            config1_lower = config1.lower()
            config2_lower = config2.lower()
            output_obj = os.path.join(self.tmp_dir,
                                      config1_lower + '_' + config2_lower)
            command = self.target_run + [output_obj]
            verbose_print_command(command)
            returncode = subprocess.call(command)
            assert returncode == 0, str(command)


def main():
    parser = argparse.ArgumentParser(description='Resilience test helper')
    parser.add_argument('--target-build-swift', required=True)
    parser.add_argument('--target-run', required=True)
    parser.add_argument('--t', required=True)
    parser.add_argument('--S', required=True)
    parser.add_argument('--s', required=True)
    parser.add_argument('--additional-compile-flags-library', default='')
    parser.add_argument('--no-backward-deployment', default=False,
                        action='store_true')

    args = parser.parse_args()

    resilience_test = ResilienceTest(args.target_build_swift, args.target_run,
                                     args.t, args.S, args.s,
                                     args.additional_compile_flags_library,
                                     args.no_backward_deployment)

    return resilience_test.run()


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