// Copyright 2021 Code Intelligence GmbH
//
// 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.

package com.code_intelligence.jazzer.api;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationTargetException;
import java.security.SecureRandom;

/**
 * Helper class with static methods that interact with Jazzer at runtime.
 */
final public class Jazzer {
  /**
   * A 32-bit random number that hooks can use to make pseudo-random choices
   * between multiple possible mutations they could guide the fuzzer towards.
   * Hooks <b>must not</b> base the decision whether or not to report a finding
   * on this number as this will make findings non-reproducible.
   * <p>
   * This is the same number that libFuzzer uses as a seed internally, which
   * makes it possible to deterministically reproduce a previous fuzzing run by
   * supplying the seed value printed by libFuzzer as the value of the
   * {@code -seed}.
   */
  public static final int SEED = getLibFuzzerSeed();

  private static final Class<?> JAZZER_INTERNAL;

  private static final MethodHandle ON_FUZZ_TARGET_READY;

  private static final MethodHandle TRACE_STRCMP;
  private static final MethodHandle TRACE_STRSTR;
  private static final MethodHandle TRACE_MEMCMP;
  private static final MethodHandle TRACE_PC_INDIR;

  private static final MethodHandle CONSUME;
  private static final MethodHandle AUTOFUZZ_FUNCTION_1;
  private static final MethodHandle AUTOFUZZ_FUNCTION_2;
  private static final MethodHandle AUTOFUZZ_FUNCTION_3;
  private static final MethodHandle AUTOFUZZ_FUNCTION_4;
  private static final MethodHandle AUTOFUZZ_FUNCTION_5;
  private static final MethodHandle AUTOFUZZ_CONSUMER_1;
  private static final MethodHandle AUTOFUZZ_CONSUMER_2;
  private static final MethodHandle AUTOFUZZ_CONSUMER_3;
  private static final MethodHandle AUTOFUZZ_CONSUMER_4;
  private static final MethodHandle AUTOFUZZ_CONSUMER_5;

  static {
    Class<?> jazzerInternal = null;
    MethodHandle onFuzzTargetReady = null;
    MethodHandle traceStrcmp = null;
    MethodHandle traceStrstr = null;
    MethodHandle traceMemcmp = null;
    MethodHandle tracePcIndir = null;
    MethodHandle consume = null;
    MethodHandle autofuzzFunction1 = null;
    MethodHandle autofuzzFunction2 = null;
    MethodHandle autofuzzFunction3 = null;
    MethodHandle autofuzzFunction4 = null;
    MethodHandle autofuzzFunction5 = null;
    MethodHandle autofuzzConsumer1 = null;
    MethodHandle autofuzzConsumer2 = null;
    MethodHandle autofuzzConsumer3 = null;
    MethodHandle autofuzzConsumer4 = null;
    MethodHandle autofuzzConsumer5 = null;
    try {
      jazzerInternal = Class.forName("com.code_intelligence.jazzer.runtime.JazzerInternal");
      MethodType onFuzzTargetReadyType = MethodType.methodType(void.class, Runnable.class);
      onFuzzTargetReady = MethodHandles.publicLookup().findStatic(
          jazzerInternal, "registerOnFuzzTargetReadyCallback", onFuzzTargetReadyType);
      Class<?> traceDataFlowNativeCallbacks =
          Class.forName("com.code_intelligence.jazzer.runtime.TraceDataFlowNativeCallbacks");

      // Use method handles for hints as the calls are potentially performance critical.
      MethodType traceStrcmpType =
          MethodType.methodType(void.class, String.class, String.class, int.class, int.class);
      traceStrcmp = MethodHandles.publicLookup().findStatic(
          traceDataFlowNativeCallbacks, "traceStrcmp", traceStrcmpType);
      MethodType traceStrstrType =
          MethodType.methodType(void.class, String.class, String.class, int.class);
      traceStrstr = MethodHandles.publicLookup().findStatic(
          traceDataFlowNativeCallbacks, "traceStrstr", traceStrstrType);
      MethodType traceMemcmpType =
          MethodType.methodType(void.class, byte[].class, byte[].class, int.class, int.class);
      traceMemcmp = MethodHandles.publicLookup().findStatic(
          traceDataFlowNativeCallbacks, "traceMemcmp", traceMemcmpType);
      MethodType tracePcIndirType = MethodType.methodType(void.class, int.class, int.class);
      tracePcIndir = MethodHandles.publicLookup().findStatic(
          traceDataFlowNativeCallbacks, "tracePcIndir", tracePcIndirType);

      Class<?> metaClass = Class.forName("com.code_intelligence.jazzer.autofuzz.Meta");
      MethodType consumeType =
          MethodType.methodType(Object.class, FuzzedDataProvider.class, Class.class);
      consume = MethodHandles.publicLookup().findStatic(metaClass, "consume", consumeType);

      autofuzzFunction1 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(Object.class, FuzzedDataProvider.class, Function1.class));
      autofuzzFunction2 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(Object.class, FuzzedDataProvider.class, Function2.class));
      autofuzzFunction3 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(Object.class, FuzzedDataProvider.class, Function3.class));
      autofuzzFunction4 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(Object.class, FuzzedDataProvider.class, Function4.class));
      autofuzzFunction5 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(Object.class, FuzzedDataProvider.class, Function5.class));
      autofuzzConsumer1 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer1.class));
      autofuzzConsumer2 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer2.class));
      autofuzzConsumer3 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer3.class));
      autofuzzConsumer4 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer4.class));
      autofuzzConsumer5 = MethodHandles.publicLookup().findStatic(metaClass, "autofuzz",
          MethodType.methodType(void.class, FuzzedDataProvider.class, Consumer5.class));
    } catch (ClassNotFoundException ignore) {
      // Not running in the context of the agent. This is fine as long as no methods are called on
      // this class.
    } catch (NoSuchMethodException | IllegalAccessException e) {
      // This should never happen as the Jazzer API is loaded from the agent and thus should always
      // match the version of the runtime classes.
      System.err.println("ERROR: Incompatible version of the Jazzer API detected, please update.");
      e.printStackTrace();
      System.exit(1);
    }
    JAZZER_INTERNAL = jazzerInternal;
    ON_FUZZ_TARGET_READY = onFuzzTargetReady;
    TRACE_STRCMP = traceStrcmp;
    TRACE_STRSTR = traceStrstr;
    TRACE_MEMCMP = traceMemcmp;
    TRACE_PC_INDIR = tracePcIndir;
    CONSUME = consume;
    AUTOFUZZ_FUNCTION_1 = autofuzzFunction1;
    AUTOFUZZ_FUNCTION_2 = autofuzzFunction2;
    AUTOFUZZ_FUNCTION_3 = autofuzzFunction3;
    AUTOFUZZ_FUNCTION_4 = autofuzzFunction4;
    AUTOFUZZ_FUNCTION_5 = autofuzzFunction5;
    AUTOFUZZ_CONSUMER_1 = autofuzzConsumer1;
    AUTOFUZZ_CONSUMER_2 = autofuzzConsumer2;
    AUTOFUZZ_CONSUMER_3 = autofuzzConsumer3;
    AUTOFUZZ_CONSUMER_4 = autofuzzConsumer4;
    AUTOFUZZ_CONSUMER_5 = autofuzzConsumer5;
  }

  private Jazzer() {}

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Function1} with (partially) specified
   *     type variables, e.g. {@code (Function1<String, ?>) String::new}.
   * @return the return value of {@code func}, or {@code null} if {@code autofuzz} failed to invoke
   *     the function.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  @SuppressWarnings("unchecked")
  public static <T1, R> R autofuzz(FuzzedDataProvider data, Function1<T1, R> func) {
    try {
      return (R) AUTOFUZZ_FUNCTION_1.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
    // Not reached.
    return null;
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Function2} with (partially) specified
   *     type variables.
   * @return the return value of {@code func}, or {@code null} if {@code autofuzz} failed to invoke
   *     the function.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  @SuppressWarnings("unchecked")
  public static <T1, T2, R> R autofuzz(FuzzedDataProvider data, Function2<T1, T2, R> func) {
    try {
      return (R) AUTOFUZZ_FUNCTION_2.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
    // Not reached.
    return null;
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Function3} with (partially) specified
   *     type variables.
   * @return the return value of {@code func}, or {@code null} if {@code autofuzz} failed to invoke
   *     the function.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  @SuppressWarnings("unchecked")
  public static <T1, T2, T3, R> R autofuzz(FuzzedDataProvider data, Function3<T1, T2, T3, R> func) {
    try {
      return (R) AUTOFUZZ_FUNCTION_3.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
    // Not reached.
    return null;
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Function4} with (partially) specified
   *     type variables.
   * @return the return value of {@code func}, or {@code null} if {@code autofuzz} failed to invoke
   *     the function.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  @SuppressWarnings("unchecked")
  public static <T1, T2, T3, T4, R> R autofuzz(
      FuzzedDataProvider data, Function4<T1, T2, T3, T4, R> func) {
    try {
      return (R) AUTOFUZZ_FUNCTION_4.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
    // Not reached.
    return null;
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Function5} with (partially) specified
   *     type variables.
   * @return the return value of {@code func}, or {@code null} if {@code autofuzz} failed to invoke
   *     the function.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  @SuppressWarnings("unchecked")
  public static <T1, T2, T3, T4, T5, R> R autofuzz(
      FuzzedDataProvider data, Function5<T1, T2, T3, T4, T5, R> func) {
    try {
      return (R) AUTOFUZZ_FUNCTION_5.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
    // Not reached.
    return null;
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Consumer1} with explicitly specified
   * type variable.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  public static <T1> void autofuzz(FuzzedDataProvider data, Consumer1<T1> func) {
    try {
      AUTOFUZZ_CONSUMER_1.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Consumer2} with (partially) specified
   * type variables.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  public static <T1, T2> void autofuzz(FuzzedDataProvider data, Consumer2<T1, T2> func) {
    try {
      AUTOFUZZ_CONSUMER_2.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Consumer3} with (partially) specified
   * type variables.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  public static <T1, T2, T3> void autofuzz(FuzzedDataProvider data, Consumer3<T1, T2, T3> func) {
    try {
      AUTOFUZZ_CONSUMER_3.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Consumer4} with (partially) specified
   * type variables.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  public static <T1, T2, T3, T4> void autofuzz(
      FuzzedDataProvider data, Consumer4<T1, T2, T3, T4> func) {
    try {
      AUTOFUZZ_CONSUMER_4.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
  }

  /**
   * Attempts to invoke {@code func} with arguments created automatically from the fuzzer input
   * using only public methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to execute {@code func} in
   * meaningful ways for a number of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param func a method reference for the function to autofuzz. If there are multiple overloads,
   *     resolve ambiguities by explicitly casting to {@link Consumer5} with (partially) specified
   * type variables.
   * @throws Throwable any {@link Throwable} thrown by {@code func}, or an {@link
   *     AutofuzzConstructionException} if autofuzz failed to construct the arguments for the call.
   *     The {@link Throwable} is thrown unchecked.
   */
  public static <T1, T2, T3, T4, T5> void autofuzz(
      FuzzedDataProvider data, Consumer5<T1, T2, T3, T4, T5> func) {
    try {
      AUTOFUZZ_CONSUMER_5.invoke(data, func);
    } catch (AutofuzzInvocationException e) {
      rethrowUnchecked(e.getCause());
    } catch (Throwable t) {
      rethrowUnchecked(t);
    }
  }

  /**
   * Attempts to construct an instance of {@code type} from the fuzzer input using only public
   * methods available on the classpath.
   * <p>
   * <b>Note:</b> This function is inherently heuristic and may fail to return meaningful values for
   * a variety of reasons.
   *
   * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
   * @param type the {@link Class} to construct an instance of.
   * @return an instance of {@code type} constructed from the fuzzer input, or {@code null} if
   *     autofuzz failed to create an instance.
   */
  @SuppressWarnings("unchecked")
  public static <T> T consume(FuzzedDataProvider data, Class<T> type) {
    try {
      return (T) CONSUME.invokeExact(data, type);
    } catch (AutofuzzConstructionException ignored) {
      return null;
    } catch (Throwable t) {
      rethrowUnchecked(t);
      // Not reached.
      return null;
    }
  }

  /**
   * Instructs the fuzzer to guide its mutations towards making {@code current} equal to {@code
   * target}.
   * <p>
   * If the relation between the raw fuzzer input and the value of {@code current} is relatively
   * complex, running the fuzzer with the argument {@code -use_value_profile=1} may be necessary to
   * achieve equality.
   *
   * @param current a non-constant string observed during fuzz target execution
   * @param target a string that {@code current} should become equal to, but currently isn't
   * @param id a (probabilistically) unique identifier for this particular compare hint
   */
  public static void guideTowardsEquality(String current, String target, int id) {
    if (TRACE_STRCMP == null) {
      return;
    }
    try {
      TRACE_STRCMP.invokeExact(current, target, 1, id);
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

  /**
   * Instructs the fuzzer to guide its mutations towards making {@code current} equal to {@code
   * target}.
   * <p>
   * If the relation between the raw fuzzer input and the value of {@code current} is relatively
   * complex, running the fuzzer with the argument {@code -use_value_profile=1} may be necessary to
   * achieve equality.
   *
   * @param current a non-constant byte array observed during fuzz target execution
   * @param target a byte array that {@code current} should become equal to, but currently isn't
   * @param id a (probabilistically) unique identifier for this particular compare hint
   */
  public static void guideTowardsEquality(byte[] current, byte[] target, int id) {
    if (TRACE_MEMCMP == null) {
      return;
    }
    try {
      TRACE_MEMCMP.invokeExact(current, target, 1, id);
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

  /**
   * Instructs the fuzzer to guide its mutations towards making {@code haystack} contain {@code
   * needle} as a substring.
   * <p>
   * If the relation between the raw fuzzer input and the value of {@code haystack} is relatively
   * complex, running the fuzzer with the argument {@code -use_value_profile=1} may be necessary to
   * satisfy the substring check.
   *
   * @param haystack a non-constant string observed during fuzz target execution
   * @param needle a string that should be contained in {@code haystack} as a substring, but
   *     currently isn't
   * @param id a (probabilistically) unique identifier for this particular compare hint
   */
  public static void guideTowardsContainment(String haystack, String needle, int id) {
    if (TRACE_STRSTR == null) {
      return;
    }
    try {
      TRACE_STRSTR.invokeExact(haystack, needle, id);
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

  /**
   * Instructs the fuzzer to attain as many possible values for the absolute value of {@code state}
   * as possible.
   * <p>
   * Call this function from a fuzz target or a hook to help the fuzzer track partial progress
   * (e.g. by passing the length of a common prefix of two lists that should become equal) or
   * explore different values of state that is not directly related to code coverage (see the
   * MazeFuzzer example).
   * <p>
   * <b>Note:</b> This hint only takes effect if the fuzzer is run with the argument
   * {@code -use_value_profile=1}.
   *
   * @param state a numeric encoding of a state that should be varied by the fuzzer
   * @param id a (probabilistically) unique identifier for this particular state hint
   */
  public static void exploreState(byte state, int id) {
    if (TRACE_PC_INDIR == null) {
      return;
    }
    // We only use the lower 7 bits of state, which allows for 128 different state values tracked
    // per id. The particular amount of 7 bits of state is also used in libFuzzer's
    // TracePC::HandleCmp:
    // https://github.com/llvm/llvm-project/blob/c12d49c4e286fa108d4d69f1c6d2b8d691993ffd/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp#L390
    // This value should be large enough for most use cases (e.g. tracking the length of a prefix in
    // a comparison) while being small enough that the bitmap isn't filled up too quickly
    // (65536 bits/ 128 bits per id = 512 ids).

    // We use tracePcIndir as a way to set a bit in libFuzzer's value profile bitmap. In
    // TracePC::HandleCallerCallee, which is what this function ultimately calls through to, the
    // lower 12 bits of each argument are combined into a 24-bit index into the bitmap, which is
    // then reduced modulo a 16-bit prime. To keep the modulo bias small, we should fill as many
    // of the relevant bits as possible. However, there are the following restrictions:
    // 1. Since we use the return address trampoline to set the caller address indirectly, its
    //    upper 3 bits are fixed, which leaves a total of 21 variable bits on x86_64.
    // 2. On arm64 macOS, where every instruction is aligned to 4 bytes, the lower 2 bits of the
    //    caller address will always be zero, further reducing the number of variable bits in the
    //    caller parameter to 7.
    // https://github.com/llvm/llvm-project/blob/c12d49c4e286fa108d4d69f1c6d2b8d691993ffd/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp#L121
    // Even taking these restrictions into consideration, we pass state in the lowest bits of the
    // caller address, which is used to form the lowest bits of the bitmap index. This should result
    // in the best caching behavior as state is expected to change quickly in consecutive runs and
    // in this way all its bitmap entries would be located close to each other in memory.
    int lowerBits = (state & 0x7f) | (id << 7);
    int upperBits = id >>> 5;
    try {
      TRACE_PC_INDIR.invokeExact(upperBits, lowerBits);
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

  /**
   * Make Jazzer report the provided {@link Throwable} as a finding.
   * <p>
   * <b>Note:</b> This method must only be called from a method hook. In a
   * fuzz target, simply throw an exception to trigger a finding.
   * @param finding the finding that Jazzer should report
   */
  public static void reportFindingFromHook(Throwable finding) {
    try {
      JAZZER_INTERNAL.getMethod("reportFindingFromHook", Throwable.class).invoke(null, finding);
    } catch (NullPointerException | IllegalAccessException | NoSuchMethodException e) {
      // We can only reach this point if the runtime is not on the classpath, e.g. in case of a
      // reproducer. Just throw the finding.
      rethrowUnchecked(finding);
    } catch (InvocationTargetException e) {
      // reportFindingFromHook throws a HardToCatchThrowable, which will bubble up wrapped in an
      // InvocationTargetException that should not be stopped here.
      if (e.getCause().getClass().getName().endsWith(".HardToCatchError")) {
        throw(Error) e.getCause();
      } else {
        e.printStackTrace();
      }
    }
  }

  /**
   * Register a callback to be executed right before the fuzz target is executed for the first time.
   * <p>
   * This can be used to disable hooks until after Jazzer has been fully initializing, e.g. to
   * prevent Jazzer internals from triggering hooks on Java standard library classes.
   *
   * @param callback the callback to execute
   */
  public static void onFuzzTargetReady(Runnable callback) {
    try {
      ON_FUZZ_TARGET_READY.invokeExact(callback);
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

  private static int getLibFuzzerSeed() {
    // The Jazzer driver sets this property based on the value of libFuzzer's -seed command-line
    // option, which allows for fully reproducible fuzzing runs if set. If not running in the
    // context of the driver, fall back to a random number instead.
    String rawSeed = System.getProperty("jazzer.seed");
    if (rawSeed == null) {
      return new SecureRandom().nextInt();
    }
    // If jazzer.seed is set, we expect it to be a valid integer.
    return Integer.parseUnsignedInt(rawSeed);
  }

  // Rethrows a (possibly checked) exception while avoiding a throws declaration.
  @SuppressWarnings("unchecked")
  private static <T extends Throwable> void rethrowUnchecked(Throwable t) throws T {
    throw(T) t;
  }
}
