# Copyright 2020 Google LLC
#
# 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
#
#     https://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.

"""The implementation of the {cc, java}_fuzz_test rules."""

load("@rules_cc//cc:defs.bzl", "cc_binary")

# FIXME: Including this leads to a Stardoc error since defs.bzl is not visible. As a workaround, use native.java_binary.
#load("@rules_java//java:defs.bzl", "java_binary")
load("//fuzzing/private:common.bzl", "fuzzing_corpus", "fuzzing_dictionary", "fuzzing_launcher")
load("//fuzzing/private:binary.bzl", "fuzzing_binary", "fuzzing_binary_uninstrumented")
load("//fuzzing/private:java_utils.bzl", "determine_primary_class", "jazzer_fuzz_binary")
load("//fuzzing/private:regression.bzl", "fuzzing_regression_test")
load("//fuzzing/private/oss_fuzz:package.bzl", "oss_fuzz_package")

def fuzzing_decoration(
        name,
        raw_binary,
        engine,
        corpus = None,
        dicts = None,
        instrument_binary = True,
        define_regression_test = True,
        test_tags = None):
    """Generates the standard targets associated to a fuzz test.

    This macro can be used to define custom fuzz test rules in case the default
    `cc_fuzz_test` macro is not adequate. Refer to the `cc_fuzz_test` macro
    documentation for the set of targets generated.

    Args:
        name: The name prefix of the generated targets. It is normally the
          fuzz test name in the BUILD file.
        raw_binary: The label of the cc_binary or cc_test of fuzz test
          executable.
        engine: The label of the fuzzing engine used to build the binary.
        corpus: A list of corpus files.
        dicts: A list of fuzzing dictionary files.
        instrument_binary: **(Experimental, may be removed in the future.)**

          By default, the generated targets depend on `raw_binary` through
          a Bazel configuration using flags from the `@rules_fuzzing//fuzzing`
          package to determine the fuzzing build mode, engine, and sanitizer
          instrumentation.

          When this argument is false, the targets assume that `raw_binary` is
          already built in the proper configuration and will not apply the
          transition.

          Most users should not need to change this argument. If you think the
          default instrumentation mode does not work for your use case, please
          file a Github issue to discuss.
        define_regression_test: If true, generate a regression test rule.
        test_tags: Tags set on the fuzzing regression test.
    """

    # We tag all non-test targets as "manual" in order to optimize the build
    # size output of test runs in RBE mode. Otherwise, "bazel test" commands
    # build all the non-test targets by default and, in remote builds, all these
    # targets and their runfiles would be transferred from the remote cache to
    # the local machine, ballooning the size of the output.

    instrum_binary_name = name + "_bin"
    launcher_name = name + "_run"
    corpus_name = name + "_corpus"
    dict_name = name + "_dict"

    if instrument_binary:
        fuzzing_binary(
            name = instrum_binary_name,
            binary = raw_binary,
            engine = engine,
            corpus = corpus_name,
            dictionary = dict_name if dicts else None,
            testonly = True,
            tags = ["manual"],
        )
    else:
        fuzzing_binary_uninstrumented(
            name = instrum_binary_name,
            binary = raw_binary,
            engine = engine,
            corpus = corpus_name,
            dictionary = dict_name if dicts else None,
            testonly = True,
            tags = ["manual"],
        )

    fuzzing_corpus(
        name = corpus_name,
        srcs = corpus,
        testonly = True,
    )

    if dicts:
        fuzzing_dictionary(
            name = dict_name,
            dicts = dicts,
            output = name + ".dict",
            testonly = True,
        )

    fuzzing_launcher(
        name = launcher_name,
        binary = instrum_binary_name,
        testonly = True,
        tags = ["manual"],
    )

    if define_regression_test:
        fuzzing_regression_test(
            name = name,
            binary = instrum_binary_name,
            tags = test_tags,
        )

    oss_fuzz_package(
        name = name + "_oss_fuzz",
        base_name = name,
        binary = instrum_binary_name,
        testonly = True,
        tags = ["manual"],
    )

def cc_fuzz_test(
        name,
        corpus = None,
        dicts = None,
        engine = "@rules_fuzzing//fuzzing:cc_engine",
        tags = None,
        **binary_kwargs):
    """Defines a C++ fuzz test and a few associated tools and metadata.

    For each fuzz test `<name>`, this macro defines a number of targets. The
    most relevant ones are:

    * `<name>`: A test that executes the fuzzer binary against the seed corpus
      (or on an empty input if no corpus is specified).
    * `<name>_bin`: The instrumented fuzz test executable. Use this target
      for debugging or for accessing the complete command line interface of the
      fuzzing engine. Most developers should only need to use this target
      rarely.
    * `<name>_run`: An executable target used to launch the fuzz test using a
      simpler, engine-agnostic command line interface.
    * `<name>_oss_fuzz`: Generates a `<name>_oss_fuzz.tar` archive containing
      the fuzz target executable and its associated resources (corpus,
      dictionary, etc.) in a format suitable for unpacking in the $OUT/
      directory of an OSS-Fuzz build. This target can be used inside the
      `build.sh` script of an OSS-Fuzz project.

    Args:
        name: A unique name for this target. Required.
        corpus: A list containing corpus files.
        dicts: A list containing dictionaries.
        engine: A label pointing to the fuzzing engine to use.
        tags: Tags set on the fuzzing regression test.
        **binary_kwargs: Keyword arguments directly forwarded to the fuzz test
          binary rule.
    """

    # Append the '_' suffix to the raw target to dissuade users from referencing
    # this target directly. Instead, the binary should be built through the
    # instrumented configuration.
    raw_binary_name = name + "_raw_"
    binary_kwargs.setdefault("deps", [])

    # Use += rather than append to allow users to pass in select() expressions for
    # deps, which only support concatenation with +.
    # Workaround for https://github.com/bazelbuild/bazel/issues/14157.
    # buildifier: disable=list-append
    binary_kwargs["deps"] += [engine]

    # tags is not configurable and can thus use append.
    binary_kwargs.setdefault("tags", []).append("manual")
    cc_binary(
        name = raw_binary_name,
        **binary_kwargs
    )

    fuzzing_decoration(
        name = name,
        raw_binary = raw_binary_name,
        engine = engine,
        corpus = corpus,
        dicts = dicts,
        test_tags = (tags or []) + [
            "fuzz-test",
        ],
    )

def java_fuzz_test(
        name,
        srcs = None,
        target_class = None,
        corpus = None,
        dicts = None,
        engine = "@rules_fuzzing//fuzzing:java_engine",
        tags = None,
        **binary_kwargs):
    """Defines a Java fuzz test and a few associated tools and metadata.

    For each fuzz test `<name>`, this macro defines a number of targets. The
    most relevant ones are:

    * `<name>`: A test that executes the fuzzer binary against the seed corpus
      (or on an empty input if no corpus is specified).
    * `<name>_bin`: The instrumented fuzz test executable. Use this target
      for debugging or for accessing the complete command line interface of the
      fuzzing engine. Most developers should only need to use this target
      rarely.
    * `<name>_run`: An executable target used to launch the fuzz test using a
      simpler, engine-agnostic command line interface.
    * `<name>_oss_fuzz`: Generates a `<name>_oss_fuzz.tar` archive containing
      the fuzz target executable and its associated resources (corpus,
      dictionary, etc.) in a format suitable for unpacking in the $OUT/
      directory of an OSS-Fuzz build. This target can be used inside the
      `build.sh` script of an OSS-Fuzz project.

    Args:
        name: A unique name for this target. Required.
        srcs: A list of source files of the target.
        target_class: The class that contains the static fuzzerTestOneInput
          method. Defaults to the same class main_class would.
        corpus: A list containing corpus files.
        dicts: A list containing dictionaries.
        engine: A label pointing to the fuzzing engine to use.
        tags: Tags set on the fuzzing regression test.
        **binary_kwargs: Keyword arguments directly forwarded to the fuzz test
          binary rule.
    """

    # Append the '_' suffix to the raw target to dissuade users from referencing
    # this target directly. Instead, the binary should be built through the
    # instrumented configuration.
    raw_target_name = name + "_target_"

    # Determine a value for target_class heuristically using the same rules as
    # those used by Bazel internally for main_class.
    # FIXME: This operates on the raw unresolved srcs list entries and thus
    #  cannot handle labels.
    if not target_class:
        target_class = determine_primary_class(srcs, name)
    if not target_class:
        fail(("Unable to determine fuzz target class for java_fuzz_test {name}" +
              ", specify target_class.").format(
            name = name,
        ))
    target_class_manifest_line = "Jazzer-Fuzz-Target-Class: %s" % target_class
    binary_kwargs.setdefault("deps", [])

    # Use += rather than append to allow users to pass in select() expressions for
    # deps, which only support concatenation with +.
    # Workaround for https://github.com/bazelbuild/bazel/issues/14157.
    # buildifier: disable=list-append
    binary_kwargs["deps"] += [engine]
    binary_kwargs.setdefault("deploy_manifest_lines", [])

    # buildifier: disable=list-append
    binary_kwargs["deploy_manifest_lines"] += [target_class_manifest_line]

    # tags is not configurable and can thus use append.
    binary_kwargs.setdefault("tags", []).append("manual")
    native.java_binary(
        name = raw_target_name,
        srcs = srcs,
        create_executable = False,
        **binary_kwargs
    )

    raw_binary_name = name + "_raw_"
    jazzer_fuzz_binary(
        name = raw_binary_name,
        agent = select({
            "@rules_fuzzing//fuzzing/private:use_oss_fuzz": "@rules_fuzzing_oss_fuzz//:jazzer_agent_deploy.jar",
            "//conditions:default": "@jazzer//agent:jazzer_agent_deploy.jar",
        }),
        # Since the choice of sanitizer is explicit for local fuzzing, we also
        # let it apply to projects with no native dependencies.
        driver_java_only = select({
            "@rules_fuzzing//fuzzing/private:use_oss_fuzz": "@rules_fuzzing_oss_fuzz//:jazzer_driver",
            "@rules_fuzzing//fuzzing/private:use_sanitizer_none": "@jazzer//driver:jazzer_driver",
            "@rules_fuzzing//fuzzing/private:use_sanitizer_asan": "@jazzer//driver:jazzer_driver_asan",
        }, no_match_error = "Jazzer only supports the sanitizer settings \"none\" and \"asan\""),
        driver_with_native = select({
            "@rules_fuzzing//fuzzing/private:use_oss_fuzz": "@rules_fuzzing_oss_fuzz//:jazzer_driver_with_sanitizer",
            "@rules_fuzzing//fuzzing/private:use_sanitizer_none": "@jazzer//driver:jazzer_driver",
            "@rules_fuzzing//fuzzing/private:use_sanitizer_asan": "@jazzer//driver:jazzer_driver_asan",
        }, no_match_error = "Jazzer only supports the sanitizer settings \"none\" and \"asan\""),
        sanitizer_options = select({
            "@rules_fuzzing//fuzzing/private:use_oss_fuzz": "@rules_fuzzing//fuzzing/private:oss_fuzz_jazzer_sanitizer_options.sh",
            "//conditions:default": "@rules_fuzzing//fuzzing/private:local_jazzer_sanitizer_options.sh",
        }),
        tags = ["manual"],
        target = raw_target_name,
        target_deploy_jar = raw_target_name + "_deploy.jar",
    )

    fuzzing_decoration(
        name = name,
        raw_binary = raw_binary_name,
        # jazzer_fuzz_binary already instrumented the native dependencies.
        instrument_binary = False,
        engine = engine,
        corpus = corpus,
        dicts = dicts,
        test_tags = (tags or []) + [
            "fuzz-test",
        ],
    )
