#!/usr/bin/env python3.8
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os
import sys
import unittest

from .host import Host
from .fuzzer import Fuzzer

# This file contains the top-level implementations for each of the subcommands
# for "fx fuzz".


def list_fuzzers(args, factory):
    """Implementation of "fx fuzz list"."""
    buildenv = factory.buildenv
    fuzzer_tests = buildenv.fuzzer_tests(args.name)
    match_prefix = ' matching' if args.name else ''
    match_suffix = ' for "{}"'.format(args.name) if args.name else ''
    if fuzzer_tests:
        plural = 's' if len(fuzzer_tests) != 1 else ''
        factory.host.echo(
            'Found {}{} fuzzer test{}{}:'.format(
                len(fuzzer_tests), match_prefix, plural, match_suffix))
        for fuzzer_test in fuzzer_tests:
            factory.host.echo('  ' + str(fuzzer_test) + '_test')

        if plural:
            target_was_not_selected = 'These tests correspond to fuzzers, but were not selected by the build arguments'
        else:
            target_was_not_selected = 'This test corresponds to a fuzzer, but was not selected by the build arguments'
        factory.host.echo(
            '', target_was_not_selected,
            'to be built with a fuzzer toolchain variant.', '',
            'To select them, you can use `fx set ... --fuzz-with <sanitizer>`.',
            'See https://fuchsia.dev/fuchsia-src/development/testing/fuzzing/build-a-fuzzer',
            'for additional details.', '')

    fuzzers = buildenv.fuzzers(args.name)
    if fuzzers:
        plural = 's' if len(fuzzers) != 1 else ''
        factory.host.echo(
            'Found {}{} fuzzer{}{}:'.format(
                len(fuzzers), match_prefix, plural, match_suffix))
        for fuzzer in fuzzers:
            factory.host.echo('  ' + str(fuzzer))
    else:
        factory.host.echo(
            'No{} fuzzers found{}.'.format(match_prefix, match_suffix))


def start_fuzzer(args, factory):
    """Implementation of "fx fuzz start"."""
    fuzzer = factory.create_fuzzer(args)
    if not args.monitor:
        factory.host.echo(
            'Starting {}.'.format(fuzzer),
            'Outputs will be written to: {}'.format(fuzzer.output))
        if not args.foreground:
            factory.host.echo(
                'Check status with "fx fuzz check {}".'.format(fuzzer),
                'Stop manually with "fx fuzz stop {}".'.format(fuzzer))
        fuzzer.start()
        if not args.foreground:
            cmd = ['python3.8', sys.argv[0], 'start', '--monitor']
            if fuzzer.output:
                cmd += ['--output', fuzzer.output]
            cmd.append(str(fuzzer))
            return factory.host.create_process(cmd).popen()
    else:
        fuzzer.monitor()
        factory.host.echo(
            '{} has stopped.'.format(fuzzer),
            'Output written to: {}.'.format(fuzzer.output))


def check_fuzzer(args, factory):
    """Implementation of "fx fuzz check"."""
    blank = True
    for fuzzer in factory.buildenv.fuzzers(args.name):
        if not args.name and not fuzzer.is_running():
            continue
        if not fuzzer.is_resolved():
            factory.host.echo('{}: NOT INSTALLED'.format(fuzzer))
        elif fuzzer.is_running(refresh=True):
            factory.host.echo('{}: RUNNING'.format(fuzzer))
        else:
            factory.host.echo('{}: STOPPED'.format(fuzzer))
        if fuzzer.is_resolved():
            num, size = fuzzer.corpus.measure()
            factory.host.echo(
                '    Corpus size:  {} inputs / {} bytes'.format(num, size))
        artifacts = fuzzer.list_artifacts()
        if artifacts:
            factory.host.echo('    Artifacts:')
            for artifact in artifacts:
                factory.host.echo('        {}'.format(artifact))
        factory.host.echo('')
        blank = False
    if blank:
        factory.host.echo(
            'No fuzzers are running.',
            'Include \'name\' to check specific fuzzers.')


def stop_fuzzer(args, factory):
    """Implementation of "fx fuzz stop"."""
    fuzzer = factory.create_fuzzer(args)
    if fuzzer.is_running():
        factory.host.echo('Stopping {}.'.format(fuzzer))
        fuzzer.stop()
    else:
        factory.host.echo('{} is already stopped.'.format(fuzzer))


def repro_units(args, factory):
    """Implementation of "fx fuzz repro"."""
    fuzzer = factory.create_fuzzer(args)
    fuzzer.repro()


def analyze_fuzzer(args, factory):
    """Implementation of "fx fuzz analyze"."""
    fuzzer = factory.create_fuzzer(args)

    if args.corpora:
        for corpus in args.corpora:
            fuzzer.corpus.add_from_host(corpus)
    if args.dict:
        fuzzer.dictionary.replace(args.dict)
    if not args.local:
        fuzzer.corpus.add_from_gcs(fuzzer.clusterfuzz_gcs_url)
    fuzzer.analyze()


def update_corpus(args, factory):
    """Implementation of "fx fuzz update"."""
    # Factory.create_fuzzer interprets args.output as the place to store logs, which is not what we
    # want here.
    build_gn = None
    if args.output:
        build_gn = factory.buildenv.abspath(args.output)
    args.output = None
    fuzzer = factory.create_fuzzer(args, include_tests=True)
    elems = fuzzer.corpus.generate_buildfile(build_gn=build_gn)
    if len(elems) == 0:
        factory.host.echo('Empty corpus added.')
    else:
        factory.host.echo('Added:')
        for elem in elems:
            factory.host.echo('  ' + elem)
    if not build_gn:
        build_gn = '{}/BUILD.gn'.format(fuzzer.corpus.srcdir)
    else:
        build_gn = '//' + os.path.relpath(
            build_gn, factory.buildenv.fuchsia_dir)
    factory.host.echo('', build_gn + ' updated.')


def _run_tests(pattern, factory):
    # __file__ is scripts/fuzzing/lib/command.py
    lib_dir = os.path.dirname(os.path.abspath(__file__))
    # ../test
    test_dir = os.path.join(os.path.dirname(lib_dir), 'test')
    # scripts/fuzzing/lib/../../ => scripts/
    top_level_dir = os.path.dirname(os.path.dirname(lib_dir))
    tests = unittest.defaultTestLoader.discover(test_dir, pattern=pattern, top_level_dir=top_level_dir)
    if factory.host.tracing:
        os.environ[Host.TRACE_ENVVAR] = '1'
        verbosity = 2
    else:
        verbosity = 1
    unittest.runner.TextTestRunner(verbosity=verbosity).run(tests)


def run_e2e_test(args, factory):
    """Runs the end-to-end test against a (resolved) fuzzer, if specified."""
    if args.name:
        # Use Factory.create_fuzzer to resolve the fuzzer name, prompting the
        # user if needed.
        fuzzer = factory.create_fuzzer(args)
        sys.argv[sys.argv.index(args.name)] = str(fuzzer)
    _run_tests('test_e2e.py', factory)


def measure_coverage(args, factory):
    """Generates a coverage report of specified fuzzers."""
    fuzzer = factory.create_fuzzer(args, include_tests=True)
    fuzzer.generate_coverage_report(local=args.local, input_dirs=args.input)
