#!/usr/bin/env python3

# Copyright 2026 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.

"""Run and monitor the Binaryen fuzzer (fuzz_opt.py).

Monitors progress, manages log file truncation, stops at iteration limits,
and reports bugs found.
"""

import argparse
import collections
import os
import re
import signal
import subprocess
import sys
import threading
import time


# Duplicated from test.shared (importing test.shared has unwanted side effects).
def get_num_cores():
    # Prefer `os.process_cpu_count` when available (3.13 and above) since it
    # takes into account thread affinity. Fall back to `os.sched_getaffinity`
    # where available and finally `os.cpu_count`, which should work everywhere.
    if hasattr(os, 'process_cpu_count'):
        cpu_count = os.process_cpu_count()
    elif hasattr(os, 'sched_getaffinity'):
        cpu_count = len(os.sched_getaffinity(0))
    else:
        cpu_count = os.cpu_count()
    return int(os.getenv('BINARYEN_CORES', cpu_count))


class FuzzMonitor:
    """Monitors fuzzer output stream, manages log files, and tracks state."""

    def __init__(self, log_path, max_lines, keep_lines, truncate_interval):
        self.log_path = log_path
        self.max_lines = max_lines
        self.keep_lines = keep_lines
        self.truncate_interval = truncate_interval

        self.lock = threading.Lock()
        self.latest_iteration = 0
        self.latest_seed = 'unknown'
        self.bug_found = False
        self.recent_lines = collections.deque(maxlen=20)

        self.deque = collections.deque(maxlen=keep_lines)
        self.lines_written = 0

        if os.path.isfile(log_path):
            try:
                with open(log_path, encoding='utf-8', errors='replace') as f:
                    for line in f:
                        self.deque.append(line)
                        self.lines_written += 1
            except Exception:
                pass

    def _parse_line(self, line):
        iter_match = re.search(r'ITERATION:\s*(\d+)', line)
        if iter_match:
            self.latest_iteration = int(iter_match.group(1))

        seed_match = re.search(r'seed:\s*(\d+)', line)
        if seed_match:
            self.latest_seed = seed_match.group(1)

        if re.search(r'You found a bug', line, re.IGNORECASE):
            self.bug_found = True

    def run(self, stdout_stream):
        last_truncate = time.time()
        try:
            with open(self.log_path, 'a', encoding='utf-8') as f:
                for line in stdout_stream:
                    with self.lock:
                        self._parse_line(line)
                        self.deque.append(line)
                        self.recent_lines.append(line)
                        self.lines_written += 1

                    f.write(line)
                    f.flush()

                    now = time.time()
                    if (
                        self.lines_written >= self.max_lines
                        and (now - last_truncate) >= self.truncate_interval
                    ):
                        f.close()
                        with open(self.log_path, 'w', encoding='utf-8') as wf:
                            with self.lock:
                                wf.writelines(self.deque)
                                self.lines_written = len(self.deque)
                        f = open(self.log_path, 'a', encoding='utf-8')
                        last_truncate = now
        except Exception as e:
            print(f'Error writing to log file: {e}', file=sys.stderr)

    def get_progress(self):
        with self.lock:
            return self.latest_iteration

    def get_status(self):
        with self.lock:
            return (
                self.bug_found,
                self.latest_iteration,
                self.latest_seed,
                list(self.recent_lines),
            )


class FuzzerWorker:
    """Manages a single fuzzer subprocess and its monitor."""

    def __init__(
        self,
        worker_id,
        work_dir,
        cmd,
        env,
        max_lines,
        keep_lines,
        truncate_interval,
    ):
        self.id = worker_id
        self.work_dir = work_dir
        os.makedirs(work_dir, exist_ok=True)
        self.log_path = os.path.join(work_dir, 'fuzz.log')
        self.monitor = FuzzMonitor(
            log_path=self.log_path,
            max_lines=max_lines,
            keep_lines=keep_lines,
            truncate_interval=truncate_interval,
        )
        worker_env = env.copy()
        worker_env['BINARYEN_OUT_DIR'] = work_dir
        self.proc = subprocess.Popen(
            cmd,
            cwd=work_dir,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1,
            env=worker_env,
            errors='replace',
            start_new_session=True,
        )
        self.reader_thread = threading.Thread(
            target=self.monitor.run,
            args=(self.proc.stdout,),
            daemon=True,
        )
        self.reader_thread.start()


def parse_args():
    # N.B. We could alternatively `import shared from test`, which has the side
    # effect of changing the current directory to <binaryen_root>/out/test, but
    # this is less magical.
    binaryen_root = os.path.dirname(
        os.path.dirname(os.path.abspath(__file__)))
    default_log_dir = os.path.join(binaryen_root, 'out', 'test')
    cores = get_num_cores() or 1
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '-j',
        '--jobs',
        type=int,
        nargs='?',
        const=cores,
        default=int(os.environ.get('JOBS', '1')),
        help=(
            f'Number of parallel fuzzers to run (default: $JOBS or 1; '
            f'defaults to {cores} if passed without an argument)'
        ),
    )
    parser.add_argument(
        '--log-dir',
        default=os.environ.get('LOG_DIR', default_log_dir),
        help='Directory to save fuzz logs (default: $LOG_DIR or out/test)',
    )
    parser.add_argument(
        '--max-iters',
        type=int,
        default=int(os.environ.get('MAX_ITERS', '0')),
        help='Stop after N total iterations across all fuzzers (0 for infinite, default: $MAX_ITERS or 0)',
    )
    parser.add_argument(
        '--truncate-interval',
        type=float,
        default=30.0,
        help='Seconds between log truncation checks (default: 30)',
    )
    parser.add_argument(
        '--max-lines',
        type=int,
        default=10000,
        help='Maximum lines in log before truncation (default: 10000)',
    )
    parser.add_argument(
        '--keep-lines',
        type=int,
        default=5000,
        help='Lines to keep when truncating (default: 5000)',
    )
    parser.add_argument(
        'cmd',
        nargs=argparse.REMAINDER,
        help='Fuzzer command to run (default: ./scripts/fuzz_opt.py)',
    )
    args = parser.parse_args()
    if args.jobs < 1:
        parser.error('--jobs must be at least 1')
    return args


def main():
    args = parse_args()

    cmd = list(args.cmd)
    if cmd and cmd[0] == '--':
        cmd.pop(0)
    if not cmd:
        default_fuzzer = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'fuzz_opt.py',
        )
        cmd = [sys.executable, default_fuzzer]
    else:
        cmd = [
            os.path.abspath(arg) if os.path.exists(arg) else arg for arg in cmd
        ]

    env = os.environ.copy()
    env['PYTHONUNBUFFERED'] = '1'

    workers = []
    for i in range(args.jobs):
        work_dir = os.path.join(args.log_dir, str(i))
        workers.append(
            FuzzerWorker(
                worker_id=i,
                work_dir=work_dir,
                cmd=cmd,
                env=env,
                max_lines=args.max_lines,
                keep_lines=args.keep_lines,
                truncate_interval=args.truncate_interval,
            ),
        )

    if len(workers) == 1:
        print(
            f'Fuzzer started with PID {workers[0].proc.pid}. Monitoring...',
            flush=True,
        )
    else:
        pids = ', '.join(str(w.proc.pid) for w in workers)
        print(
            f'Started {len(workers)} fuzzers with PIDs {pids}. Monitoring...',
            flush=True,
        )

    def stop_children():
        for w in workers:
            if w.proc.poll() is None:
                try:
                    os.killpg(w.proc.pid, signal.SIGTERM)
                except ProcessLookupError:
                    pass
        deadline = time.time() + 5.0
        for w in workers:
            if w.proc.poll() is None:
                remaining = max(0.0, deadline - time.time())
                try:
                    w.proc.wait(timeout=remaining)
                except subprocess.TimeoutExpired:
                    try:
                        os.killpg(w.proc.pid, signal.SIGKILL)
                    except ProcessLookupError:
                        pass
                    w.proc.wait()

    def signal_handler(signum, _frame):
        stop_children()
        for w in workers:
            w.reader_thread.join(timeout=2.0)
        sys.exit(128 + signum)

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    start_time = time.time()
    last_report = 0
    limit_reached = False
    stopped_worker = None

    try:
        while any(
            w.reader_thread.is_alive() or w.proc.poll() is None for w in workers
        ):
            time.sleep(0.2)
            now = time.time()
            elapsed = int(now - start_time)

            minute = elapsed // 60
            total_iters = sum(w.monitor.get_progress() for w in workers)

            if minute > last_report:
                last_report = minute
                timestamp = time.strftime('%H:%M:%S')
                print(
                    f'[{timestamp}] Runtime: {last_report} min,'
                    f' Iterations: {total_iters}',
                    flush=True,
                )

            if args.max_iters > 0 and total_iters >= args.max_iters:
                fuzzer_str = 'fuzzer' if len(workers) == 1 else 'fuzzers'
                print(
                    f'Reached max iterations ({args.max_iters}). Stopping'
                    f' {fuzzer_str}...',
                    flush=True,
                )
                limit_reached = True
                stop_children()
                break

            should_stop = False
            for w in workers:
                if w.monitor.get_status()[0]:
                    try:
                        w.proc.wait(timeout=2.0)
                    except subprocess.TimeoutExpired:
                        pass
                    w.reader_thread.join(timeout=2.0)
                    stopped_worker = w
                    should_stop = True
                    break
                if w.proc.poll() is not None:
                    w.reader_thread.join(timeout=2.0)
                    stopped_worker = w
                    should_stop = True
                    break

            if should_stop:
                stop_children()
                break
    finally:
        stop_children()
        for w in workers:
            w.reader_thread.join(timeout=5.0)

    for w in workers:
        bug_found, iteration, seed, _ = w.monitor.get_status()
        if bug_found:
            print('SUCCESS: Bug found!')
            if len(workers) > 1:
                print(f'Fuzzer: {w.id}')
            print(f'Directory: {w.work_dir}')
            print(f'Iteration: {iteration}')
            print(f'Seed: {seed}')
            print(f'Exit code: {w.proc.returncode}')
            return 1

    if limit_reached:
        print(
            f'SUCCESS: Reached max iterations ({args.max_iters}) without finding'
            ' a bug.',
        )
        return 0

    failed_worker = stopped_worker or workers[0]
    _, _, _, recent_lines = failed_worker.monitor.get_status()

    print('FAILURE: Fuzzer stopped unexpectedly without finding a bug.')
    if len(workers) > 1:
        print(f'Fuzzer: {failed_worker.id}')
    print(f'Directory: {failed_worker.work_dir}')
    print(f'Exit code: {failed_worker.proc.returncode}')
    if recent_lines:
        print('Last 20 lines of log:')
        for line in recent_lines:
            print(line.rstrip('\r\n'))
    return 2


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