#!/usr/bin/env python3
# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#
"""
This script minimizes a program generated by dartfuzz.dart.
"""

import argparse
import multiprocessing as mp
import re
import shlex
import subprocess

STATEMENT_MASK_LINE = 0
STATEMENT_NUMBER_LINE = 1
EXPRESSION_MASK_LINE = 2
EXPRESSION_NUMBER_LINE = 3


class MaskGen(object):
    """
    Generates bitpatterns of <nbits> bits which indicate which
    statements or expressions should be masked when passed as the
    --smask or --emask parameter to dartfuzz.dart.
    The patterns are generated in the following manner:
    11111111111111111111111111111111
    11111111111111110000000000000000
    00000000000000001111111111111111
    11111111111111111111111100000000
    11111111111111110000000011111111
    11111111000000001111111111111111
    00000000111111111111111111111111
    ...
    If the error persists with a given a pattern it is stored in the
    parameter <mask>.
    """

    def __init__(self, nbits, mask):
        # Mask bitlength.
        self.nbits = nbits
        # Mask determining which statements or expressions to skip.
        self.mask = mask
        # Current mask modification start index.
        self.convolution_idx = 0
        # Max mask with all bits set to 1.
        self.max = (1 << (nbits + 1)) - 1
        # Current number of bits set in the mask modification mask.
        self.nbitsVar = int(nbits)
        # Current mask modification mask.
        # This will be folded over the current value of self.mask
        # starting from 0.
        self.filter_mask = (1 << self.nbitsVar) - 1
        # All the masks already tested.
        self.tested = set()
        self.gen_new_mask = False

    def __iter__(self):
        return self

    def __next__(self):
        return self.next()

    # Update the set of tested masks.
    # This is used to keep track of tested masks that did not produce a crash.
    def update_tested(self, new_mask):
        self.tested.add(new_mask)

    # Update the current mask with the new mask that produced a crash.
    # Note: We assume that if mask
    # 11110000 produces a crash and
    # 00000011 produces a crash that
    # 11110011 will also produce a crash.
    # This might not be true for some cases.
    def update_mask(self, new_mask):
        new_mask = (self.mask | new_mask) & self.max
        self.mask = new_mask

    # Count the bits of the current mask.
    # More bits mean more statements omitted, so this is used
    # to determine the quality of the current mask.
    def count_bits(self):
        return bin(self.mask).count('1')

    def inc_var(self):
        self.convolution_idx = 0
        self.nbitsVar = self.nbitsVar >> 1
        self.filter_mask = (1 << self.nbitsVar) - 1
        return self.filter_mask == 0

    def stop(self):
        if self.convolution_idx >= self.nbits and self.inc_var() > 0:
            # Check if the last run generated a new mask.
            if self.gen_new_mask:
                # Restart mask generation from beginning.
                self.nbitsVar = self.nbits >> 1
                self.inc_var()
                self.gen_new_mask = False
                return False
            print("STOP")
            return True
        return False

    def next(self):
        while not self.stop():
            # Generate a new mask according to the mask generation algorithm.
            new_mask = (self.mask |
                        (self.filter_mask << self.convolution_idx)) & self.max
            # Update the counter variable for the mask generation algorithm.
            self.convolution_idx += self.nbitsVar
            # If the new_mask has new bits and has not been tested yet.
            # We need to check both because only masks that produce an
            # error are merged into self.mask.
            if new_mask != self.mask and \
                new_mask not in self.tested:
                # Add new mask to the set of tested masks.
                self.tested.add(new_mask)
                # Mark that we generated a new mask on this run.
                self.gen_new_mask = True
                # Return the new mask to be tested.
                return new_mask
        raise StopIteration()


# Generate a Dart program for the given statement (smask) and
# expression (emask) masks. Dartfuzz parameters for seed, ffi and
# fp are static and therefore contained in the dartfuzz_cmd parameter.
def generate_dart(dartfuzz_cmd, dart_test, smask, mask, do_expr):
    if do_expr:
        # Minimizing expressions.
        cmds = shlex.split(dartfuzz_cmd) + [dart_test] + \
            ['--mini', '--smask', '%d' % smask, '--emask', '%d' % mask]
        p = subprocess.Popen(cmds, stdout=subprocess.PIPE)
    else:
        # Minimizing statements.
        cmds = shlex.split(dartfuzz_cmd) + [dart_test] + \
            ['--mini', '--smask', '%d' % mask]
        p = subprocess.Popen(cmds, stdout=subprocess.PIPE)
    p_stdout, p_stderr = p.communicate()
    if p.returncode != 0:
        raise 'Invalid return code on generate %d' % p.returncode
    mask_new = 0
    if do_expr:
        mask_new = int(p_stdout.decode().splitlines()[EXPRESSION_MASK_LINE])
    else:
        mask_new = int(p_stdout.decode().splitlines()[STATEMENT_MASK_LINE])
    return mask_new


# Run the Dart program and check for error (by matching error_match_p).
def run_dart(dart_cmd, dart_test, error_match_p, timeout):
    cmd = ['timeout', str(timeout)] + shlex.split(dart_cmd) + [dart_test]
    p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    p_stdout, p_stderr = p.communicate()
    if error_match_p.search(p_stdout.decode()) or \
        error_match_p.search(p_stderr.decode()):
        return True
    if p.returncode != 0:
        print("Warning: error return code %d" % p.returncode)
    return False


# Run multiple tries of the given dart_cmd and check for errors by matching
# against error_match_p.
def run_dart_mp(dart_cmd, dart_test, error_match_p, tries, nthreads, timeout):
    if tries == 1:
        return run_dart(dart_cmd, dart_test, error_match_p, timeout)
    pool = mp.Pool(nthreads)
    results = [
        pool.apply_async(run_dart,
                         (dart_cmd, dart_test, error_match_p, timeout))
        for i in range(tries)
    ]
    worker_done = [False for i in range(tries)]
    while True:
        all_done = True
        for i, result in enumerate(results):
            if worker_done[i]:
                continue
            try:
                r = result.get(timeout=0.5)
                worker_done[i] = True
                if r:
                    pool.close()
                    pool.terminate()
                    pool.join()
                    return True
            except mp.TimeoutError:
                all_done = False
        if all_done:
            break
    pool.close()
    pool.join()
    return False


def minimize(dartfuzz_cmd,
             dart_cmd,
             dart_cmd_ref,
             dart_test,
             error_match1,
             error_match2,
             smask,
             emask,
             do_expr,
             verbose,
             tries,
             tries_ref,
             threads,
             timeout,
             print_every=32):
    # Run dartfuzz command once to get the total number of statements
    # and expressions in the generated program.
    # Output will look like this:
    # <Current Statement Mask>
    # <Number of Statements>
    # <Current Expression Mask>
    # <Number of Expressions>
    p = subprocess.Popen(
        dartfuzz_cmd + " --mini " + dart_test,
        shell=True,
        stdout=subprocess.PIPE)
    p_stdout, p_stderr = p.communicate()
    if do_expr:
        # Minimizing expressions.
        nstmts = int(p_stdout.decode().splitlines()[EXPRESSION_NUMBER_LINE])
        mask_gen = MaskGen(nstmts, emask)
    else:
        # Minimizing statements.
        nstmts = int(p_stdout.decode().splitlines()[STATEMENT_NUMBER_LINE])
        mask_gen = MaskGen(nstmts, smask)
    # Best mask found so far.
    min_mask = 0
    # Maximum number of statements or expressions masked.
    max_bits = 0
    # Count number of iterations.
    cntr = 0
    # Result of the last run.
    last_err = True
    # Compile pattern to match standard output and error for a string
    # identifying the crash.
    error_match_p1 = re.compile(error_match1)
    error_match_p2 = None
    if error_match2 is not None:
        error_match_p2 = re.compile(error_match2)
    for mask in mask_gen:
        if (verbose):
            print("Mask: %x" % mask)
        cntr += 1
        if cntr % print_every == 0:
            cntr = 0
            print("Best I could do so far is mask %d/%d" \
                  % (max_bits, nstmts))
            if do_expr:
                print(dartfuzz_cmd + " " + dart_test +
                      " --mini --smask 0x%x --emask 0x%x" % (smask, min_mask))
            else:
                print(dartfuzz_cmd + " " + dart_test +
                      " --mini --smask 0x%x --emask 0" % (min_mask))
        # The return value mask_new contains the actual mask applied by
        # dartfuzz. Due to nesting, masking one statement might lead to other
        # statements being masked as well; mask_new will contain this updated
        # mask.
        mask_new = generate_dart(dartfuzz_cmd, dart_test, smask, mask, do_expr)
        # Run generated Dart program and check for error.
        err = run_dart_mp(dart_cmd, dart_test, error_match_p1, tries, threads,
                          timeout)
        if err and verbose:
            print("Matched error 1 " + error_match1)
        err_ref = True
        if (dart_cmd_ref is not None) and (error_match_p2 is not None):
            err_ref = run_dart_mp(dart_cmd_ref, dart_test, error_match_p2,
                                  tries_ref, threads, timeout)
            if err_ref and verbose:
                print("Matched error 2 " + error_match2)
        if err and err_ref:
            # In case the mask used for generating the Dart program lead to an
            # error, update the mask generator accordingly.
            mask_gen.update_mask(mask)
            # TODO (felih): this line should be enough but there seems to be a
            # bug in dartfuzz.dart calculating mask_new.
            mask_gen.update_mask(mask_new)
            max_bits = mask_gen.count_bits()
            min_mask = mask_gen.mask
        elif last_err:
            # If the last run removed the error try the inverse.
            invMaskNew = mask_gen.mask | (mask_gen.max & ~mask_new)
            if invMaskNew != mask_gen.mask and \
                invMaskNew not in mask_gen.tested:
                if (verbose):
                    print("Mask: %x (i)" % invMaskNew)
                mask_new = generate_dart(dartfuzz_cmd, dart_test, smask,
                                         invMaskNew, do_expr)
                err = run_dart_mp(dart_cmd, dart_test, error_match_p1, tries,
                                  threads, timeout)
                if err and verbose:
                    print("Matched error 1 " + error_match1)
                err_ref = True
                if (dart_cmd_ref is not None) and (error_match_p2 is not None):
                    err_ref = run_dart_mp(dart_cmd_ref, dart_test,
                                          error_match_p2, tries_ref, threads,
                                          timeout)
                    if err_ref and verbose:
                        print("Matched error 2 " + error_match2)
                if err and err_ref:
                    mask_gen.update_mask(invMaskNew)
                    mask_gen.update_mask(mask_new)
                    max_bits = mask_gen.count_bits()
                    min_mask = mask_gen.mask
        last_err = err and err_ref
        # Update the set of tested masks with the one we just tested.
        mask_gen.update_tested(mask_new)

    print("Best I could do is %d/%d" \
          % (max_bits,nstmts))

    if do_expr:
        print(dartfuzz_cmd + " " + dart_test +
              " --mini --smask 0x%x --emask 0x%x" % (smask, min_mask))
    else:
        print(dartfuzz_cmd + " " + dart_test +
              " --mini --smask 0x%x --emask 0" % (min_mask))

    return min_mask


def main():
    parser = argparse.ArgumentParser(
        description='Minimize a generated Dart program ' +
        ' while maintaining an identified crash or divergence. ' +
        'A second Dart program can be specified for divergence testing.')
    parser.add_argument(
        '--dartfuzz',
        required=True,
        help="dartfuzz command string "
        "e.g. dart dartfuzz.dart --no-ffi --no-fp --seed 243123600")
    parser.add_argument(
        '--dart',
        help="Dart command string "
        "e.g. ./sdk/out/ReleaseX64/dart",
        required=True)
    parser.add_argument(
        '--dart-ref',
        dest="dart_ref",
        help="Dart command string for reference build " +
        "(in case of divergence testing) " + "e.g. ./sdk/out/ReleaseX64/dart",
        default=None)
    parser.add_argument(
        '--testfile',
        required=True,
        help="output filename for program generated by "
        "dartfuzz command and passed to Dart command "
        "e.g fuzz.dart")
    parser.add_argument(
        '--err',
        help="string indicating an error for Dart cmd (no multiline matches)",
        required=True)
    parser.add_argument(
        '--err-ref',
        dest="err_ref",
        help="string matching the diverging output for the Dart " +
        "reference command (no multiline matches)",
        default=None)
    parser.add_argument(
        '--smask', help="hexadecimal statements mask", default="0")
    parser.add_argument(
        '--emask', help="hexadecimal expressions mask", default="0")
    parser.add_argument(
        '--typ',
        choices=["s", "e", "se"],
        required=True,
        help="minimize statements (s) or expressions (e) or both (se)")
    parser.add_argument(
        '--tries',
        type=int,
        default=1,
        help='number of retries per run for Dart cmd')
    parser.add_argument(
        '--tries-ref',
        type=int,
        dest='tries_ref',
        default=1,
        help='number of retries per run for Dart reference cmd')
    parser.add_argument(
        '--threads',
        type=int,
        default=4,
        help='number of threads to use for retries')
    parser.add_argument(
        '--timeout', type=int, default=60, help='timeout for Dart command')
    parser.add_argument(
        '--verbose', help="print intermediate results", action="store_true")
    args = parser.parse_args()
    timeout = args.timeout
    do_stmt = "s" in args.typ
    do_expr = "e" in args.typ
    smask = int(args.smask, 16)
    if do_stmt:
        print("Minimizing Statements")
        smask = minimize(args.dartfuzz, args.dart, args.dart_ref,
                         args.testfile, args.err, args.err_ref, smask,
                         int(args.emask, 16), False, args.verbose, args.tries,
                         args.tries_ref, args.threads, timeout)
    if do_expr:
        print("Minimizing Expressions")
        minimize(args.dartfuzz, args.dart, args.dart_ref,
                 args.testfile, args.err, args.err_ref, smask,
                 int(args.emask, 16), True, args.verbose, args.tries,
                 args.tries_ref, args.threads, timeout)


if __name__ == "__main__":
    main()
