#!/usr/bin/env python3
#
# Copyright 2016 WebAssembly Community Group participants
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

'''
This fuzzes passes, by starting with a working program, then running
random passes on the wast, and seeing if they break something

Usage: Provide a base filename for a runnable program, e.g. a.out.js.
       Then we will modify a.out.wast. Note that the program must
       be built to run using that wast (BINARYEN_METHOD=interpret-s-expr)

       Other parameters after the first are used when calling the program.
'''


import os
import random
import shutil
import subprocess
import sys

PASSES = [
    "duplicate-function-elimination",
    "dce",
    "remove-unused-brs",
    "remove-unused-names",
    "optimize-instructions",
    "precompute",
    "simplify-locals",
    "vacuum",
    "coalesce-locals",
    "reorder-locals",
    "merge-blocks",
    "remove-unused-functions",
]

# main

base = sys.argv[1]
wast = base[:-3] + '.wast'
print('>>> base program:', base, ', wast:', wast)

args = sys.argv[2:]


def run():
    if os.path.exists(wast):
        print('>>> running using a wast of size', os.stat(wast).st_size)
    cmd = ['mozjs', base] + args
    try:
        return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    except Exception as e:
        print(">>> !!! ", e, " !!!")


original_wast = None

try:
    # get normal output

    normal = run()
    print('>>> normal output:\n', normal)
    assert normal, 'must be output'

    # ensure we actually use the wast

    original_wast = wast + '.original.wast'
    shutil.move(wast, original_wast)
    assert run() != normal, 'running without the wast must fail'

    # ensure a bad pass makes it fail

    def apply_passes(passes):
        wasm_opt = os.path.join('bin', 'wasm-opt')
        subprocess.check_call([wasm_opt, original_wast] + passes + ['-o', wast])

    apply_passes(['--remove-imports'])
    assert run() != normal, 'running after a breaking pass must fail'

    # loop, looking for failures

    def simplify(passes):
        # passes is known to fail, try to simplify down by removing
        more = True
        while more:
            more = False
            print('>>> trying to reduce:', ' '.join(passes), '  [' + str(len(passes)) + ']')
            for i in range(len(passes)):
                smaller = passes[:i] + passes[i + 1:]
                print('>>>>>> try to reduce to:', ' '.join(smaller), '  [' + str(len(smaller)) + ']')
                try:
                    apply_passes(smaller)
                    assert run() == normal
                except Exception:
                    # this failed too, so it's a good reduction
                    passes = smaller
                    print('>>> reduction successful')
                    more = True
                    break
        print('>>> reduced to:', ' '.join(passes))

    tested = set()

    def pick_passes():
        ret = []
        while 1:
            str_ret = str(ret)
            if random.random() < 0.1 and str_ret not in tested:
                tested.add(str_ret)
                return ret
            ret.append('--' + random.choice(PASSES))

    counter = 0

    while 1:
        passes = pick_passes()
        print('>>> [' + str(counter) + '] testing:', ' '.join(passes))
        counter += 1
        try:
            apply_passes(passes)
        except Exception as e:
            print(e)
            simplify(passes)
            break
        seen = run()
        if seen != normal:
            print('>>> bad output:\n', seen)
            simplify(passes)
            break

finally:
    if original_wast:
        shutil.move(original_wast, wast)
