// Copyright 2019 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.

package codegen

const tmplSource = `
{{- define "Source" -}}
// WARNING: This file is machine generated by fidlgen.

#include <{{ .PrimaryHeader }}>

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/fuzzing/fuzzer.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/zx/channel.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

using namespace ::fuzzing;
using namespace {{ range .Library }}::{{ . }}{{ end }};

{{- $protocols := Protocols .Decls }}

// Add //build/fuzzing:fuzzing_verbose_logging to a GN target's configs to enable.
#if FUZZING_VERBOSE_LOGGING
#include <stdio.h>
#define xprintf(fmt...) printf(fmt)
#else
#define xprintf(fmt...) \
  do {                  \
  } while (0)
#endif

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data_, size_t size_) {
  static ::async::Loop* loop_ = nullptr;

  if (loop_ == nullptr) {
    xprintf("Starting client async loop\n");
    loop_ = new ::async::Loop(&kAsyncLoopConfigAttachToCurrentThread);
  }

  // Must fuzz some protocol; first two bytes used to select protocol and method.
  if (size_ < 2) {
    xprintf("Early exit: Input too small: %zu\n", size_);
    return 0;
  }
  size_ -= 2;

  uint8_t protocol_selector_ = data_[0];
  uint8_t protocol_selection_ = protocol_selector_ % {{ len $protocols }};

  xprintf("Starting fuzzer with %zu bytes of data\n", size_);

  // Hardcode mutually-exclusive if blocks that selects exactly one protocol.
  zx_status_t status_;
{{- range $protocolIdx, $protocol := $protocols }}{{ if len $protocol.Methods }}
  if (protocol_selection_ == {{ $protocolIdx }}) {
#if !defined(PROTOCOL_{{ DoubleColonToUnderscore $protocol.Namespace }}_{{ $protocol.Name }})
    // Selected protocol from FIDL file that is not part of this fuzzer.
    xprintf("Early exit: Chose disabled protocol: {{ DoubleColonToUnderscore $protocol.Namespace }}_{{ $protocol.Name }}\n");
    return 0;
#else

    ::fidl::InterfacePtr<{{ $protocol.Namespace }}::{{ $protocol.Name }}> protocol_;

    xprintf("Starting {{ DoubleColonToUnderscore $protocol.Namespace }}_{{ $protocol.Name }} service\n");
    ::fidl::fuzzing::Fuzzer<{{ $protocol.Namespace }}::{{ $protocol.Name }}> fuzzer_(loop_->dispatcher());
    if ((status_ = fuzzer_.Init()) != ZX_OK) {
      xprintf("Early exit: fuzzer.Init returned bad status: %d\n", status_);
      return 0;
    }

    if ((status_ = fuzzer_.BindService()) != ZX_OK) {
      xprintf("Early exit: fuzzer.BindService returned bad status: %d\n", status_);
      return 0;
    }

    if ((status_ = fuzzer_.BindClient(&protocol_, loop_->dispatcher())) != ZX_OK) {
      xprintf("Early exit: fuzzer.BindClient returned bad status: %d\n", status_);
      return 0;
    }

    FuzzInput src_(data_, size_);

    uint8_t method_selector_ = data_[1];
    uint8_t method_selection_ = method_selector_ % {{ len $protocol.Methods }};

  {{- range $methodIdx, $method := .Methods }}{{- if len $method.Request }}
    if (method_selection_ == {{ $methodIdx }}) {
#if !(ALL_METHODS || defined(METHOD_{{ $method.Name }}))
      // Selected method from protocol that is not part of this fuzzer.
      xprintf("Early exit: Chose disabled method: {{ $method.Name }}\n");
      return 0;
#else
      const size_t min_size_ = {{ range $paramIdx, $param := $method.Request }}
        {{- if $paramIdx }} + {{ end }}MinSize<{{ $param.Type.Decl }}>()
      {{- end }};

      // Must have enough bytes for input.
      if (size_ < min_size_) {
        xprintf("Early exit: Input size too small: %zu < %zu\n", size_, min_size_);
        return 0;
      }

      const size_t slack_size_ = size_ - min_size_;
      const size_t slack_size_per_param = slack_size_ / {{ len $method.Request }};

      xprintf("Allocating parameters with %zu bytes (%zu bytes each)\n", slack_size_, slack_size_per_param);

      size_t param_size_;
  {{- range $method.Request }}
      param_size_ = MinSize<{{ .Type.Decl }}>() + slack_size_per_param;
      xprintf("Allocating %zu bytes for {{ .Type.Decl }} {{ .Name }}\n", param_size_);
      {{ .Type.Decl }} {{ .Name }} = Allocate<{{ .Type.Decl }}>{}(&src_, &param_size_);
  {{- end }}

      xprintf("Invoking method {{ DoubleColonToUnderscore $protocol.Namespace }}_{{ $protocol.Name }}.{{ $method.Name }}\n");
      protocol_->{{ $method.Name }}({{ range $paramIdx, $param := $method.Request }}
          {{- if $paramIdx }}, {{ end -}}
          std::move({{ $param.Name }})
        {{- end }}
        {{- if len $method.Response}}
          {{- if len $method.Request }}, {{ end -}}
          [signaller = fuzzer_.NewCallbackSignaller()]({{ range $paramIdx, $param := $method.Response }}
            {{- if $paramIdx }}, {{ end -}}
            {{ $param.Type.Decl }} {{ $param.Name }}
          {{- end }}) {
        xprintf("Invoked {{ DoubleColonToUnderscore $protocol.Namespace }}_{{ $protocol.Name }}.{{ $method.Name }}\n");
        zx_status_t status_ = signaller.SignalCallback();
        if (status_ != ZX_OK) {
          xprintf("signaller.SignalCallback returned bad status: %d\n", status_);
        }
      }
      {{- end }});
#endif
    }
  {{- end }}{{- end }}

    loop_->RunUntilIdle();

    if ((status_ = fuzzer_.WaitForCallback()) != ZX_OK) {
      xprintf("fuzzer.WaitForCallback returned bad status: %d\n", status_);
    }

    protocol_.Unbind();
#endif
  }
{{- end }}{{ end }}

  xprintf("Fuzzer stopped!\n");

  return 0;
}
{{ end }}
`
