'''
Runs random passes and options on random inputs, using wasm-opt.

Can be configured to run just wasm-opt itself (using --fuzz-exec)
or also run VMs on it.

For afl-fuzz integration, you probably don't want this, and can use
something like

BINARYEN_CORES=1 BINARYEN_PASS_DEBUG=1 afl-fuzz -i afl-testcases/ -o afl-findings/ -m 100 -d -- bin/wasm-opt -ttf --fuzz-exec --Os @@

(that is on a fixed set of arguments to wasm-opt, though - this
script covers different options being passed)
'''

import os
import difflib
import subprocess
import random
import re
import shutil
import sys
import time

from test import shared


# parameters

NANS = True

# feature options that are always passed to the tools.
# exceptions: https://github.com/WebAssembly/binaryen/issues/2195
# simd: known issues with d8
# atomics, bulk memory: doesn't work in wasm2js
# truncsat: https://github.com/WebAssembly/binaryen/issues/2198
CONSTANT_FEATURE_OPTS = ['--all-features']

FUZZ_OPTS = []

INPUT_SIZE_LIMIT = 150 * 1024


# utilities


def in_binaryen(*args):
    return os.path.join(shared.options.binaryen_root, *args)


def in_bin(tool):
    return os.path.join(shared.options.binaryen_root, 'bin', tool)


def random_size():
    return random.randint(1, INPUT_SIZE_LIMIT)


def run(cmd):
    print(' '.join(cmd))
    return subprocess.check_output(cmd)


def run_unchecked(cmd):
    print(' '.join(cmd))
    return subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]


def randomize_pass_debug():
    if random.random() < 0.125:
        print('[pass-debug]')
        os.environ['BINARYEN_PASS_DEBUG'] = '1'
    else:
        os.environ['BINARYEN_PASS_DEBUG'] = '0'
        del os.environ['BINARYEN_PASS_DEBUG']


def randomize_feature_opts():
    global FEATURE_OPTS
    FEATURE_OPTS = CONSTANT_FEATURE_OPTS[:]
    # half the time apply all the possible opts. this lets all test runners work at max
    # capacity at least half the time, as otherwise if they need almost all the opts, the
    # chance of getting them is exponentially small.
    if random.random() < 0.5:
        FEATURE_OPTS += POSSIBLE_FEATURE_OPTS
    else:
        for possible in POSSIBLE_FEATURE_OPTS:
            if random.random() < 0.5:
                FEATURE_OPTS.append(possible)
    print('feature opts:', ' '.join(FEATURE_OPTS))


# Test outputs we want to ignore are marked this way.
IGNORE = '[binaryen-fuzzer-ignore]'


def compare(x, y, context):
    if x != y and x != IGNORE and y != IGNORE:
        message = ''.join([a + '\n' for a in difflib.unified_diff(x.splitlines(), y.splitlines(), fromfile='expected', tofile='actual')])
        raise Exception(context + " comparison error, expected to have '%s' == '%s', diff:\n\n%s" % (
            x, y,
            message
        ))


def fix_output(out):
    # large doubles may print slightly different on different VMs
    def fix_double(x):
        x = x.group(1)
        if 'nan' in x or 'NaN' in x:
            x = 'nan'
        else:
            x = x.replace('Infinity', 'inf')
            x = str(float(x))
        return 'f64.const ' + x
    out = re.sub(r'f64\.const (-?[nanN:abcdefxIity\d+-.]+)', fix_double, out)

    # mark traps from wasm-opt as exceptions, even though they didn't run in a vm
    out = out.replace('[trap ', 'exception: [trap ')

    # exceptions may differ when optimizing, but an exception should occur. so ignore their types
    # also js engines print them out slightly differently
    return '\n'.join(map(lambda x: '     *exception*' if 'exception' in x else x, out.splitlines()))


def fix_spec_output(out):
    out = fix_output(out)
    # spec shows a pointer when it traps, remove that
    out = '\n'.join(map(lambda x: x if 'runtime trap' not in x else x[x.find('runtime trap'):], out.splitlines()))
    # https://github.com/WebAssembly/spec/issues/543 , float consts are messed up
    out = '\n'.join(map(lambda x: x if 'f32' not in x and 'f64' not in x else '', out.splitlines()))
    return out


def run_vm(cmd):
    # ignore some vm assertions, if bugs have already been filed
    known_issues = [
        'local count too large',    # ignore this; can be caused by flatten, ssa, etc. passes
        'liftoff-assembler.cc, line 239\n',    # https://bugs.chromium.org/p/v8/issues/detail?id=8631
        'liftoff-assembler.cc, line 245\n',    # https://bugs.chromium.org/p/v8/issues/detail?id=8631
        'liftoff-register.h, line 86\n',    # https://bugs.chromium.org/p/v8/issues/detail?id=8632
    ]
    try:
        return run(cmd)
    except subprocess.CalledProcessError:
        output = run_unchecked(cmd)
        for issue in known_issues:
            if issue in output:
                return IGNORE
        raise


MAX_INTERPRETER_ENV_VAR = 'BINARYEN_MAX_INTERPRETER_DEPTH'
MAX_INTERPRETER_DEPTH = 1000


def run_bynterp(wasm, args):
    # increase the interpreter stack depth, to test more things
    os.environ[MAX_INTERPRETER_ENV_VAR] = str(MAX_INTERPRETER_DEPTH)
    try:
        return run_vm([in_bin('wasm-opt'), wasm] + FEATURE_OPTS + args)
    finally:
        del os.environ['BINARYEN_MAX_INTERPRETER_DEPTH']


def run_d8(wasm):
    return run_vm([shared.V8] + shared.V8_OPTS + [in_binaryen('scripts', 'fuzz_shell.js'), '--', wasm])


# There are two types of test case handlers:
#    * get_commands() users: these return a list of commands to run (for example, "run this wasm-opt
#        command, then that one"). The calling code gets and runs those commands on the test wasm
#        file, and has enough information and control to be able to perform auto-reduction of any
#        bugs found.
#    * Totally generic: These receive the input pattern, a wasm generated from it, and a wasm
#        optimized from that, and can then do anything it wants with those.
class TestCaseHandler:
    # If the core handle_pair() method is not overridden, it calls handle_single()
    # on each of the pair. That is useful if you just want the two wasms, and don't
    # care about their relationship
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        self.handle(before_wasm)
        self.handle(after_wasm)

    def can_run_on_feature_opts(self, feature_opts):
        return True


# Run VMs and compare results
class CompareVMs(TestCaseHandler):
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        run([in_bin('wasm-opt'), before_wasm, '--emit-js-wrapper=a.js', '--emit-spec-wrapper=a.wat'] + FEATURE_OPTS)
        run([in_bin('wasm-opt'), after_wasm, '--emit-js-wrapper=b.js', '--emit-spec-wrapper=b.wat'] + FEATURE_OPTS)
        before = self.run_vms('a.js', before_wasm)
        after = self.run_vms('b.js', after_wasm)
        self.compare_vs(before, after)

    def run_vms(self, js, wasm):
        results = []
        results.append(fix_output(run_bynterp(wasm, ['--fuzz-exec-before'])))
        results.append(fix_output(run_vm([shared.V8, js] + shared.V8_OPTS + ['--', wasm])))

        # append to add results from VMs
        # results += [fix_output(run_vm([shared.V8, js] + shared.V8_OPTS + ['--', wasm]))]
        # results += [fix_output(run_vm([os.path.expanduser('~/.jsvu/jsc'), js, '--', wasm]))]
        # spec has no mechanism to not halt on a trap. so we just check until the first trap, basically
        # run(['../spec/interpreter/wasm', wasm])
        # results += [fix_spec_output(run_unchecked(['../spec/interpreter/wasm', wasm, '-e', open(prefix + 'wat').read()]))]

        if len(results) == 0:
            results = [0]

        # NaNs are a source of nondeterminism between VMs; don't compare them
        if not NANS:
            first = results[0]
            for i in range(len(results)):
                compare(first, results[i], 'CompareVMs at ' + str(i))

        return results

    def compare_vs(self, before, after):
        for i in range(len(before)):
            compare(before[i], after[i], 'CompareVMs at ' + str(i))
            # with nans, we can only compare the binaryen interpreter to itself
            if NANS:
                break

    def can_run_on_feature_opts(self, feature_opts):
        return all([x in feature_opts for x in ['--disable-simd', '--disable-reference-types', '--disable-exception-handling']])


# Fuzz the interpreter with --fuzz-exec. This tests everything in a single command (no
# two separate binaries) so it's easy to reproduce.
class FuzzExec(TestCaseHandler):
    def get_commands(self, wasm, opts, random_seed):
        return [
            '%(MAX_INTERPRETER_ENV_VAR)s=%(MAX_INTERPRETER_DEPTH)d %(wasm_opt)s --fuzz-exec --fuzz-binary %(opts)s %(wasm)s' % {
                'MAX_INTERPRETER_ENV_VAR': MAX_INTERPRETER_ENV_VAR,
                'MAX_INTERPRETER_DEPTH': MAX_INTERPRETER_DEPTH,
                'wasm_opt': in_bin('wasm-opt'),
                'opts': ' '.join(opts),
                'wasm': wasm
            }
        ]


# As FuzzExec, but without a separate invocation. This can find internal bugs with generating
# the IR (which might be worked around by writing it and then reading it).
class FuzzExecImmediately(TestCaseHandler):
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        # fuzz binaryen interpreter itself. separate invocation so result is easily reduceable
        run_bynterp(before_wasm, ['--fuzz-exec', '--fuzz-binary'] + opts)


# Check for determinism - the same command must have the same output.
# Note that this doesn't use get_commands() intentionally, since we are testing
# for something that autoreduction won't help with anyhow (nondeterminism is very
# hard to reduce).
class CheckDeterminism(TestCaseHandler):
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        # check for determinism
        run([in_bin('wasm-opt'), before_wasm, '-o', 'b1.wasm'] + opts)
        run([in_bin('wasm-opt'), before_wasm, '-o', 'b2.wasm'] + opts)
        assert open('b1.wasm').read() == open('b2.wasm').read(), 'output must be deterministic'


class Wasm2JS(TestCaseHandler):
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        compare(self.run(before_wasm), self.run(after_wasm), 'Wasm2JS')

    def run(self, wasm):
        # TODO: wasm2js does not handle nans precisely, and does not
        # handle oob loads etc. with traps, should we use
        #     FUZZ_OPTS += ['--no-fuzz-nans']
        #     FUZZ_OPTS += ['--no-fuzz-oob']
        # ?
        wrapper = run([in_bin('wasm-opt'), wasm, '--emit-js-wrapper=/dev/stdout'] + FEATURE_OPTS)
        cmd = [in_bin('wasm2js'), wasm, '--emscripten']
        if random.random() < 0.5:
            cmd += ['-O']
        main = run(cmd + FEATURE_OPTS)
        with open(os.path.join(shared.options.binaryen_root, 'scripts', 'wasm2js.js')) as f:
            glue = f.read()
        with open('js.js', 'w') as f:
            f.write(glue)
            f.write(main)
            f.write(wrapper)
        out = fix_output(run_vm([shared.NODEJS, 'js.js', 'a.wasm']))
        if 'exception' in out:
            # exception, so ignoring - wasm2js does not have normal wasm trapping, so opts can eliminate a trap
            out = IGNORE
        return out

    def can_run_on_feature_opts(self, feature_opts):
        return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-threads', '--disable-bulk-memory', '--disable-nontrapping-float-to-int', '--disable-tail-call', '--disable-sign-ext', '--disable-reference-types']])


class Asyncify(TestCaseHandler):
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        # we must legalize in order to run in JS
        run([in_bin('wasm-opt'), before_wasm, '--legalize-js-interface', '-o', before_wasm] + FEATURE_OPTS)
        run([in_bin('wasm-opt'), after_wasm, '--legalize-js-interface', '-o', after_wasm] + FEATURE_OPTS)
        before = fix_output(run_d8(before_wasm))
        after = fix_output(run_d8(after_wasm))

        # TODO: also something that actually does async sleeps in the code, say
        # on the logging commands?
        # --remove-unused-module-elements removes the asyncify intrinsics, which are not valid to call

        def do_asyncify(wasm):
            cmd = [in_bin('wasm-opt'), wasm, '--asyncify', '-o', 't.wasm']
            if random.random() < 0.5:
                cmd += ['--optimize-level=%d' % random.randint(1, 3)]
            if random.random() < 0.5:
                cmd += ['--shrink-level=%d' % random.randint(1, 2)]
            cmd += FEATURE_OPTS
            run(cmd)
            out = run_d8('t.wasm')
            # emit some status logging from asyncify
            print(out.splitlines()[-1])
            # ignore the output from the new asyncify API calls - the ones with asserts will trap, too
            for ignore in ['[fuzz-exec] calling $asyncify_start_unwind\nexception!\n',
                           '[fuzz-exec] calling $asyncify_start_unwind\n',
                           '[fuzz-exec] calling $asyncify_start_rewind\nexception!\n',
                           '[fuzz-exec] calling $asyncify_start_rewind\n',
                           '[fuzz-exec] calling $asyncify_stop_rewind\n',
                           '[fuzz-exec] calling $asyncify_stop_unwind\n']:
                out = out.replace(ignore, '')
            out = '\n'.join([l for l in out.splitlines() if 'asyncify: ' not in l])
            return fix_output(out)

        before_asyncify = do_asyncify(before_wasm)
        after_asyncify = do_asyncify(after_wasm)

        compare(before, after, 'Asyncify (before/after)')
        compare(before, before_asyncify, 'Asyncify (before/before_asyncify)')
        compare(before, after_asyncify, 'Asyncify (before/after_asyncify)')

    def can_run_on_feature_opts(self, feature_opts):
        return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-tail-call', '--disable-reference-types']])


# The global list of all test case handlers
testcase_handlers = [
    FuzzExec(),
    CompareVMs(),
    CheckDeterminism(),
    Wasm2JS(),
    Asyncify(),
    FuzzExecImmediately(),
]


# Do one test, given an input file for -ttf and some optimizations to run
def test_one(random_input, opts):
    randomize_pass_debug()
    randomize_feature_opts()

    run([in_bin('wasm-opt'), random_input, '-ttf', '-o', 'a.wasm'] + FUZZ_OPTS + FEATURE_OPTS)
    wasm_size = os.stat('a.wasm').st_size
    bytes = wasm_size
    print('pre wasm size:', wasm_size)

    # first, run all handlers that use get_commands(). those don't need the second wasm in the
    # pair, since they all they do is return their commands, and expect us to run them, and
    # those commands do the actual testing, by operating on the original input wasm file. by
    # fuzzing the get_commands() ones first we can find bugs in creating the second wasm (that
    # has the opts run on it) before we try to create it later down for the passes that
    # expect to get it as one of their inputs.
    for testcase_handler in testcase_handlers:
        if testcase_handler.can_run_on_feature_opts(FEATURE_OPTS):
            if hasattr(testcase_handler, 'get_commands'):
                print('running testcase handler:', testcase_handler.__class__.__name__)
                # if the testcase handler supports giving us a list of commands, then we can get those commands
                # and use them to do useful things like automatic reduction. in this case we give it the input
                # wasm plus opts and a random seed (if it needs any internal randomness; we want to have the same
                # value there if we reduce).
                random_seed = random.random()

                # gets commands from the handler, for a given set of optimizations. this is all the commands
                # needed to run the testing that that handler wants to do.
                def get_commands(opts):
                    return testcase_handler.get_commands(wasm='a.wasm', opts=opts + FUZZ_OPTS + FEATURE_OPTS, random_seed=random_seed)

                def write_commands_and_test(opts):
                    commands = get_commands(opts)
                    write_commands(commands, 't.sh')
                    subprocess.check_call(['bash', 't.sh'])

                try:
                    write_commands_and_test(opts)
                except subprocess.CalledProcessError:
                    print('')
                    print('====================')
                    print('Found a problem! See "t.sh" for the commands, and "input.wasm" for the input. Auto-reducing to "reduced.wasm" and "tt.sh"...')
                    print('====================')
                    print('')
                    # first, reduce the fuzz opts: keep removing until we can't
                    while 1:
                        reduced = False
                        for i in range(len(opts)):
                            # some opts can't be removed, like --flatten --dfo requires flatten
                            if opts[i] == '--flatten':
                                if i != len(opts) - 1 and opts[i + 1] in ('--dfo', '--local-cse', '--rereloop'):
                                    continue
                            shorter = opts[:i] + opts[i + 1:]
                            try:
                                write_commands_and_test(shorter)
                            except subprocess.CalledProcessError:
                                # great, the shorter one is good as well
                                opts = shorter
                                print('reduced opts to ' + ' '.join(opts))
                                reduced = True
                                break
                        if not reduced:
                            break
                    # second, reduce the wasm
                    # copy a.wasm to a safe place as the reducer will use the commands on new inputs, and the commands work on a.wasm
                    shutil.copyfile('a.wasm', 'input.wasm')
                    # add a command to verify the input. this lets the reducer see that it is indeed working on the input correctly
                    commands = [in_bin('wasm-opt') + ' -all a.wasm'] + get_commands(opts)
                    write_commands(commands, 'tt.sh')
                    # reduce the input to something smaller with the same behavior on the script
                    subprocess.check_call([in_bin('wasm-reduce'), 'input.wasm', '--command=bash tt.sh', '-t', 'a.wasm', '-w', 'reduced.wasm'])
                    print('Finished reduction. See "tt.sh" and "reduced.wasm".')
                    sys.exit(1)
                print('')

    # created a second wasm for handlers that want to look at pairs.
    run([in_bin('wasm-opt'), 'a.wasm', '-o', 'b.wasm'] + opts + FUZZ_OPTS + FEATURE_OPTS)
    wasm_size = os.stat('b.wasm').st_size
    bytes += wasm_size
    print('post wasm size:', wasm_size)

    for testcase_handler in testcase_handlers:
        if testcase_handler.can_run_on_feature_opts(FEATURE_OPTS):
            if not hasattr(testcase_handler, 'get_commands'):
                print('running testcase handler:', testcase_handler.__class__.__name__)
                # let the testcase handler handle this testcase however it wants. in this case we give it
                # the input and both wasms.
                testcase_handler.handle_pair(input=random_input, before_wasm='a.wasm', after_wasm='b.wasm', opts=opts + FUZZ_OPTS + FEATURE_OPTS)
                print('')

    return bytes


def write_commands(commands, filename):
    with open(filename, 'w') as f:
        f.write('set -e\n')
        for command in commands:
            f.write('echo "%s"\n' % command)
            pre = 'BINARYEN_PASS_DEBUG=%s ' % (os.environ.get('BINARYEN_PASS_DEBUG') or '0')
            f.write(pre + command + ' &> /dev/null\n')
        f.write('echo "ok"\n')


# main

opt_choices = [
    [],
    ['-O1'], ['-O2'], ['-O3'], ['-O4'], ['-Os'], ['-Oz'],
    ["--coalesce-locals"],
    # XXX slow, non-default ["--coalesce-locals-learning"],
    ["--code-pushing"],
    ["--code-folding"],
    ["--const-hoisting"],
    ["--dae"],
    ["--dae-optimizing"],
    ["--dce"],
    ["--directize"],
    ["--flatten", "--dfo"],
    ["--duplicate-function-elimination"],
    ["--flatten"],
    # ["--fpcast-emu"], # removes indirect call failures as it makes them go through regardless of type
    ["--inlining"],
    ["--inlining-optimizing"],
    ["--flatten", "--local-cse"],
    ["--generate-stack-ir"],
    ["--licm"],
    ["--memory-packing"],
    ["--merge-blocks"],
    ['--merge-locals'],
    ["--optimize-instructions"],
    ["--optimize-stack-ir"],
    ["--generate-stack-ir", "--optimize-stack-ir"],
    ["--pick-load-signs"],
    ["--precompute"],
    ["--precompute-propagate"],
    ["--print"],
    ["--remove-unused-brs"],
    ["--remove-unused-nonfunction-module-elements"],
    ["--remove-unused-module-elements"],
    ["--remove-unused-names"],
    ["--reorder-functions"],
    ["--reorder-locals"],
    ["--flatten", "--rereloop"],
    ["--roundtrip"],
    ["--rse"],
    ["--simplify-locals"],
    ["--simplify-locals-nonesting"],
    ["--simplify-locals-nostructure"],
    ["--simplify-locals-notee"],
    ["--simplify-locals-notee-nostructure"],
    ["--ssa"],
    ["--vacuum"],
]


def get_multiple_opt_choices():
    ret = []
    # core opts
    while 1:
        choice = random.choice(opt_choices)
        if '--flatten' in ret and '--flatten' in choice:
            print('avoiding multiple --flatten in a single command, due to exponential overhead')
        else:
            ret += choice
        if len(ret) > 20 or random.random() < 0.3:
            break
    # modifiers (if not already implied by a -O? option)
    if '-O' not in str(ret):
        if random.random() < 0.5:
            ret += ['--optimize-level=' + str(random.randint(0, 3))]
        if random.random() < 0.5:
            ret += ['--shrink-level=' + str(random.randint(0, 3))]
    assert ret.count('--flatten') <= 1
    return ret


# main

if not NANS:
    FUZZ_OPTS += ['--no-fuzz-nans']

# possible feature options that are sometimes passed to the tools. this
# contains the list of all possible feature flags we can disable (after
# we enable all before that in the constant options)
POSSIBLE_FEATURE_OPTS = run([in_bin('wasm-opt'), '--print-features', '-all', in_binaryen('test', 'hello_world.wat'), '-all']).replace('--enable', '--disable').strip().split('\n')
print('POSSIBLE_FEATURE_OPTS:', POSSIBLE_FEATURE_OPTS)

if __name__ == '__main__':
    print('checking infinite random inputs')
    random.seed(time.time() * os.getpid())
    temp = 'input.dat'
    counter = 0
    bytes = 0    # wasm bytes tested
    start_time = time.time()
    while True:
        counter += 1
        f = open(temp, 'w')
        size = random_size()
        print('')
        print('ITERATION:', counter, 'size:', size, 'speed:', counter / (time.time() - start_time), 'iters/sec, ', bytes / (time.time() - start_time), 'bytes/sec\n')
        for x in range(size):
            f.write(chr(random.randint(0, 255)))
        f.close()
        opts = get_multiple_opt_choices()
        print('opts:', ' '.join(opts))
        bytes += test_one('input.dat', opts)
