from __future__ import print_function

import md5
import os
import sys

import list_reducer
from list_reducer import TESTRESULT_KEEPPREFIX
from list_reducer import TESTRESULT_KEEPSUFFIX
from list_reducer import TESTRESULT_NOFAILURE

import swift_tools


class ReduceMiscompilingFunctions(list_reducer.ListReducer):

    def __init__(self, functions, silextract, tester):
        list_reducer.ListReducer.__init__(self, functions)
        self.silextract = silextract
        self.tester = tester

    def run_test(self, prefix, suffix):
        if len(suffix) > 0 and self._test_funclist(suffix):
            return (TESTRESULT_KEEPSUFFIX, prefix, suffix)
        if len(prefix) > 0 and self._test_funclist(prefix):
            return (TESTRESULT_KEEPPREFIX, prefix, suffix)
        return (TESTRESULT_NOFAILURE, prefix, suffix)

    # Split functions in a module into two groups: Those that are under
    # consideration for miscompilation vs those that are not. Eventually, we
    # will split the module into separate partial modules and then compile so
    # we can find miscompiles. For now, we just look for crashsers in the
    # optimizer.
    def _test_funclist(self, funcs):
        funclist_hash = self.get_funclist_hash(funcs)
        funclist_path = os.path.join(self.silextract.config.work_dir,
                                     'func_list_' + funclist_hash)
        with open(funclist_path, 'w') as funclist_file:
            for f in funcs:
                funclist_file.write(f + '\n')

        print("Checking to see if the program is misoptimized with func "
              "list: %s" % funclist_path)

        # Split the module into the two halves of the program.
        (outfile_stem, outfile_invert_stem) = \
            self.get_output_filename_stems(funclist_hash)
        outfile = self.silextract.get_suffixed_filename(outfile_stem)
        outfile_invert = \
            self.silextract.get_suffixed_filename(outfile_invert_stem)
        self.silextract.invoke_with_functions(funclist_path, outfile)
        self.silextract.invoke_with_functions(funclist_path, outfile_invert,
                                              invert=True)
        return self.tester(outfile, outfile_stem, outfile_invert,
                           outfile_invert_stem)

    def get_output_filename_stems(self, funclist_hash):
        filename_stem = funclist_hash
        return (filename_stem, filename_stem + '_invert')

    def get_funclist_hash(self, funcs):
        m = md5.new()
        for f in funcs:
            m.update(f)
        return m.hexdigest()


class OptimizerTester(object):

    def __init__(self, silopt, passes):
        self.silopt = silopt
        self.result = None
        self.passes = ['-' + p for p in passes]
        m = md5.new()
        for p in passes:
            m.update(p)
        self.pass_hash = m.hexdigest()

    def get_filepaths(self, optstem, nooptstem):
        f = self.silopt.get_suffixed_filename
        return (f(optstem + '_' + self.pass_hash),
                f(nooptstem + '_' + self.pass_hash))

    def __call__(self, filepath_to_opt, filepath_to_opt_stem,
                 filepath_to_notopt, filepath_to_notopt_stem):
        (out_optpath, out_nooptpath) = \
            self.get_filepaths(filepath_to_opt_stem, filepath_to_notopt_stem)
        sys.stdout.write("Trying to optimize functions...")
        self.silopt.input_file = filepath_to_opt
        result = self.silopt.invoke_with_passlist(self.passes, out_optpath)
        if result['exit_code'] == 0:
            print(' NOCRASH!\n')
        else:
            self.result = self.silopt.input_file
            print(' CRASH!\n')
        return result['exit_code']


def function_bug_reducer(input_file, nm, sil_opt_invoker, sil_extract_invoker,
                         pass_list):
    functions = [s[1] for s in nm.get_symbols(input_file) if s[0] == 'F']

    print("Base case crashes! Trying to reduce *.sib file")

    # Otherwise, reduce the list of pases that cause the optimzier to crash.
    tester = OptimizerTester(sil_opt_invoker, pass_list)
    r = ReduceMiscompilingFunctions(functions, sil_extract_invoker,
                                    tester)
    if not r.reduce_list():
        print("Failed to find miscompiling pass list!")
    sil_opt_invoker.input_file = tester.result
    cmdline = sil_opt_invoker.cmdline_with_passlist(pass_list)
    print("*** Successfully Reduced file!")
    print("*** Final File: %s" % sil_opt_invoker.input_file)
    print("*** Final Functions: %s" % (' '.join(r.target_list)))
    print("*** Repro command line: %s" % (' '.join(cmdline)))


def invoke_function_bug_reducer(args):
    """Given a path to a sib file with canonical sil, attempt to find a perturbed
list of function given a specific pass that causes the perf pipeline to crash
    """
    tools = swift_tools.SwiftTools(args.swift_build_dir)
    config = swift_tools.SILToolInvokerConfig(args)
    nm = swift_tools.SILNMInvoker(config, tools)

    input_file = args.input_file
    extra_args = args.extra_args
    sil_opt_invoker = swift_tools.SILOptInvoker(config, tools,
                                                input_file,
                                                extra_args)

    # Make sure that the base case /does/ crash.
    filename = sil_opt_invoker.get_suffixed_filename('base_case')
    result = sil_opt_invoker.invoke_with_passlist(args.pass_list, filename)
    # If we succeed, there is no further work to do.
    if result['exit_code'] == 0:
        print("Success with PassList: %s" % (' '.join(args.pass_list)))
        return

    sil_extract_invoker = swift_tools.SILFuncExtractorInvoker(config,
                                                              tools,
                                                              input_file)

    function_bug_reducer(input_file, nm, sil_opt_invoker, sil_extract_invoker,
                         args.pass_list)


def add_parser_arguments(parser):
    """Add parser arguments for func_bug_reducer"""
    parser.set_defaults(func=invoke_function_bug_reducer)
    parser.add_argument('input_file', help='The input file to optimize')
    parser.add_argument('--module-cache', help='The module cache to use')
    parser.add_argument('--sdk', help='The sdk to pass to sil-func-extractor')
    parser.add_argument('--target', help='The target to pass to '
                        'sil-func-extractor')
    parser.add_argument('--resource-dir',
                        help='The resource-dir to pass to sil-func-extractor')
    parser.add_argument('--work-dir',
                        help='Working directory to use for temp files',
                        default='bug_reducer')
    parser.add_argument('--module-name',
                        help='The name of the module we are optimizing')
    parser.add_argument('--pass', help='pass to test', dest='pass_list',
                        action='append')
    parser.add_argument('--extra-silopt-arg', help='extra argument to pass to '
                        'sil-opt',
                        dest='extra_args', action='append')
