// Copyright 2018 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 protocolTemplateProxiesAndStubs = `
{{- define "ProtocolForwardDeclaration/ProxiesAndStubs" }}
{{ EnsureNamespace . }}
{{- IfdefFuchsia -}}
{{- .Docs }}
using {{ .Name }}Ptr = ::fidl::InterfacePtr<{{ .Name }}>;
class {{ .Proxy.Name }};
class {{ .Stub.Name }};
class {{ .EventSender.Name }};
class {{ .SyncInterface.Name }};
using {{ .Name }}SyncPtr = ::fidl::SynchronousInterfacePtr<{{ .Name }}>;
class {{ .SyncProxy.Name }};

{{ range .Methods }}
{{- EnsureNamespace .OrdinalName }}
constexpr uint64_t {{ .OrdinalName.Name }} = {{ .Ordinal | printf "%#x" }}lu;
{{- end }}

{{- EndifFuchsia -}}
{{- end }}

{{- define "Params" -}}
  {{- range $index, $param := . -}}
    {{- if $index }}, {{ end -}}{{ $param.Type }} {{ $param.Name }}
  {{- end -}}
{{ end }}

{{- define "OutParams" -}}
  {{- range $index, $param := . -}}
    {{- if $index }}, {{ end -}}{{ $param.Type }}* out_{{ $param.Name }}
  {{- end -}}
{{ end }}

{{- define "ParamTypes" -}}
  {{- range $index, $param := . -}}
    {{- if $index }}, {{ end -}}{{ $param.Type }}
  {{- end -}}
{{ end }}

{{- define "RequestMethodSignature" -}}
  {{- if .HasResponse -}}
{{ .Name }}({{ template "Params" .RequestArgs }}{{ if .RequestArgs }}, {{ end }}{{ .CallbackType }} callback)
  {{- else -}}
{{ .Name }}({{ template "Params" .RequestArgs }})
  {{- end -}}
{{ end -}}

{{- define "EventMethodSignature" -}}
{{ .Name }}({{ template "Params" .ResponseArgs }})
{{- end -}}

{{- define "SyncRequestMethodSignature" -}}
  {{- if .ResponseArgs -}}
{{ .Name }}({{ template "Params" .RequestArgs }}{{ if .RequestArgs }}, {{ end }}{{ template "OutParams" .ResponseArgs }})
  {{- else -}}
{{ .Name }}({{ template "Params" .RequestArgs }})
  {{- end -}}
{{ end -}}

{{- define "ProtocolDeclaration/ProxiesAndStubs" }}
{{- IfdefFuchsia -}}

{{- .Docs }}
class {{ .Name }} {
 public:
  using Proxy_ = {{ .Proxy }};
  using Stub_ = {{ .Stub }};
  using EventSender_ = {{ .EventSender }};
  using Sync_ = {{ .SyncInterface }};
  {{- if .DiscoverableName }}
  static const char Name_[];
  {{- end }}
  virtual ~{{ .Name }}();

  {{- range .Methods }}
    {{- if .HasResponse }}
  using {{ .CallbackType }} =
      {{ .CallbackWrapper }}<void({{ template "ParamTypes" .ResponseArgs }})>;
    {{- end }}
    {{- if .HasRequest }}
      {{ .Docs }}
      {{- if .Transitional }}
  virtual void {{ template "RequestMethodSignature" . }} { }
      {{- else }}
  virtual void {{ template "RequestMethodSignature" . }} = 0;
      {{- end }}
    {{- end }}
  {{- end }}
};

class {{ .RequestDecoder.Name }} {
 public:
  {{ .RequestDecoder.Name }}() = default;
  virtual ~{{ .RequestDecoder.Name }}() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);

  {{- range .Methods }}
    {{- if .HasRequest }}
  virtual void {{ .Name }}({{ template "Params" .RequestArgs }}) = 0;
    {{- end }}
  {{- end }}
};

class {{ .ResponseDecoder.Name }} {
 public:
  {{ .ResponseDecoder.Name }}() = default;
  virtual ~{{ .ResponseDecoder.Name }}() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);

  {{- range .Methods }}
    {{- if .HasResponse }}
  virtual void {{ .Name }}({{ template "Params" .ResponseArgs }}) = 0;
    {{- end }}
  {{- end }}
};

class {{ .EventSender.Name }} {
 public:
  virtual ~{{ .EventSender.Name }}();

  {{- range .Methods }}
    {{- if not .HasRequest }}
      {{- if .HasResponse }}
  virtual void {{ template "EventMethodSignature" . }} = 0;
      {{- end }}
    {{- end }}
  {{- end }}
};

class {{ .SyncInterface.Name }} {
 public:
  using Proxy_ = {{ .SyncProxy }};
  virtual ~{{ .SyncInterface.Name }}();

  {{- range .Methods }}
    {{- if .HasRequest }}
  virtual zx_status_t {{ template "SyncRequestMethodSignature" . }} = 0;
    {{- end }}
  {{- end }}
};

class {{ .Proxy.Name }} final : public ::fidl::internal::Proxy, public {{ .Name }} {
 public:
  explicit {{ .Proxy.Name }}(::fidl::internal::ProxyController* controller);
  ~{{ .Proxy.Name }}() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;

  {{- range .Methods }}
    {{- if .HasRequest }}
  void {{ template "RequestMethodSignature" . }} override;
    {{- else if .HasResponse }}
  {{ .CallbackType }} {{ .Name }};
    {{- end }}
  {{- end }}

 private:
  {{ .Proxy.Name }}(const {{ .Proxy }}&) = delete;
  {{ .Proxy.Name }}& operator=(const {{ .Proxy }}&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class {{ .Stub.Name }} final : public ::fidl::internal::Stub, public {{ .EventSender }} {
 public:
  typedef class {{ . }} {{ .InterfaceAliasForStub.Self }};
  explicit {{ .Stub.Name }}({{ .InterfaceAliasForStub }}* impl);
  ~{{ .Stub.Name }}() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

  {{- range .Methods }}
    {{- if not .HasRequest }}
      {{- if .HasResponse }}
  void {{ template "EventMethodSignature" . }} override;
      {{- end }}
    {{- end }}
  {{- end }}

 private:
  {{ .InterfaceAliasForStub }}* impl_;
};

class {{ .SyncProxy.Name }} : public {{ .SyncInterface }} {
 public:
  explicit {{ .SyncProxy.Name }}(::zx::channel channel);
  ~{{ .SyncProxy.Name }}() override;

  {{- range .Methods }}
    {{- if .HasRequest }}
  zx_status_t {{ template "SyncRequestMethodSignature" . }} override;
    {{- end }}
  {{- end }}

  private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<{{ .Name }}>;
};

{{- EndifFuchsia -}}
{{- end }}

{{- define "ProtocolDefinition" }}
{{- IfdefFuchsia -}}

{{- range .Methods }}
{{ if .HasRequest }}
{{ EnsureNamespace .Request.HlCodingTable }}
extern "C" const fidl_type_t {{ .Request.HlCodingTable.Name }};
{{- end }}
{{- if .HasResponse }}
{{ EnsureNamespace .Response.HlCodingTable }}
extern "C" const fidl_type_t {{ .Response.HlCodingTable.Name }};
{{- end }}
{{- end }}

{{ EnsureNamespace . }}
{{ .Name }}::~{{ .Name }}() = default;

{{- if .DiscoverableName }}
const char {{ .Name }}::Name_[] = {{ .DiscoverableName }};
{{- end }}

const fidl_type_t* {{ .RequestDecoder }}::GetType(uint64_t ordinal, bool* out_needs_response) {
  switch (ordinal) {
    {{- range .Methods }}
      {{- if .HasRequest }}
    case {{ .OrdinalName }}:
        {{- if .HasResponse }}
      *out_needs_response = true;
        {{- else }}
      *out_needs_response = false;
        {{- end }}
      return &{{ .Request.HlCodingTable }};
      {{- end }}
    {{- end }}
    default:
      *out_needs_response = false;
      return nullptr;
  }
}

const fidl_type_t* {{ .ResponseDecoder.Name }}::GetType(uint64_t ordinal) {
  switch (ordinal) {
    {{- range .Methods }}
      {{- if .HasResponse }}
    case {{ .OrdinalName }}:
      return &{{ .Response.HlCodingTable }};
      {{- end }}
    {{- end }}
    default:
      return nullptr;
  }
}

{{ .EventSender.Name }}::~{{ .EventSender.Name }}() = default;

{{ .SyncInterface.Name }}::~{{ .SyncInterface.Name }}() = default;

{{ .Proxy.Name }}::{{ .Proxy.Name }}(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

{{ .Proxy.Name }}::~{{ .Proxy.Name }}() = default;

zx_status_t {{ .Proxy.Name }}::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    {{- range .Methods }}
      {{- if not .HasRequest }}
        {{- if .HasResponse }}
    case {{ .OrdinalName }}:
    {
      if (!{{ .Name }}) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&{{ .Response.HlCodingTable }}, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &{{ .Response.HlCodingTable }}, error_msg);
        break;
      }
        {{- if .ResponseArgs }}
      ::fidl::Decoder decoder(std::move(message));
        {{- end }}
      {{ .Name }}(
        {{- range $index, $param := .ResponseArgs -}}
          {{- if $index }}, {{ end }}::fidl::DecodeAs<{{ .Type }}>(&decoder, {{ .Offset }})
        {{- end -}}
      );
      break;
    }
        {{- end }}
      {{- end }}
    {{- end }}
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

{{ range .Methods }}
  {{- if .HasRequest }}
    {{- if .HasResponse }}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
{{- /* Note: fidl::internal::SingleUseMessageHandler assumes that the lambda captures a single */}}
{{- /* fit::function. When changing CallbackType, make sure to update SingleUseMessageHandler. */}}
{{ .ResponseHandlerType }}({{ $.Name }}::{{ .CallbackType }}&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for {{ $.Name }}::{{ .Name }}\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
      {{- if .ResponseArgs }}
        ::fidl::Decoder decoder(std::move(message));
      {{- end }}
        callback_(
      {{- range $index, $param := .ResponseArgs -}}
        {{- if $index }}, {{ end }}::fidl::DecodeAs<{{ .Type }}>(&decoder, {{ .Offset }})
      {{- end -}}
        );
        return ZX_OK;
      }, &{{ .Response.HlCodingTable }});
}

}  // namespace
{{- end }}
void {{ $.Proxy.Name }}::{{ template "RequestMethodSignature" . }} {
  ::fidl::Encoder _encoder({{ .OrdinalName }});
  controller_->Send(&{{ .Request.HlCodingTable }}, {{ $.RequestEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .RequestArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  )
  {{- if .HasResponse -}}
    , {{ .ResponseHandlerType }}(std::move(callback))
  {{- else -}}
    , nullptr
  {{- end -}}
  );
}
  {{- end }}
{{- end }}

{{ .Stub.Name }}::{{ .Stub.Name }}({{ .InterfaceAliasForStub }}* impl) : impl_(impl) {
  (void)impl_;
}

{{ .Stub.Name }}::~{{ .Stub.Name }}() = default;

namespace {
{{- range .Methods }}
  {{- if .HasRequest }}
    {{- if .HasResponse }}

class {{ .ResponderType }} final {
 public:
  {{ .ResponderType }}(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()({{ template "Params" .ResponseArgs }}) {
    ::fidl::Encoder _encoder({{ .OrdinalName }});
    response_.Send(&{{ .Response.HlCodingTable }}, {{ $.ResponseEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .ResponseArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};
    {{- end }}
  {{- end }}
{{- end }}

}  // namespace

zx_status_t {{ .Stub.Name }}::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  const fidl_type_t* request_type = {{ .RequestDecoder }}::GetType(message.ordinal(), &needs_response);
  if (request_type == nullptr) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  if (response.needs_response() != needs_response) {
    if (needs_response) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message needing a response with no txid");
    } else {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid");
    }
    return ZX_ERR_INVALID_ARGS;
  }
  const char* error_msg = nullptr;
  zx_status_t status = message.Decode(request_type, &error_msg);
  if (status != ZX_OK) {
    FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
    return status;
  }
  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    {{- range .Methods }}
      {{- if .HasRequest }}
    case {{ .OrdinalName }}:
    {
        {{- if .RequestArgs }}
      ::fidl::Decoder decoder(std::move(message));
        {{- end }}
      impl_->{{ .Name }}(
        {{- range $index, $param := .RequestArgs -}}
          {{- if $index }}, {{ end }}::fidl::DecodeAs<{{ .Type }}>(&decoder, {{ .Offset }})
        {{- end -}}
        {{- if .HasResponse -}}
          {{- if .RequestArgs }}, {{ end -}}{{ .ResponderType }}(std::move(response))
        {{- end -}}
      );
      break;
    }
      {{- end }}
    {{- end }}
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

{{- range .Methods }}
  {{- if not .HasRequest }}
    {{- if .HasResponse }}
void {{ $.Stub.Name }}::{{ template "EventMethodSignature" . }} {
  ::fidl::Encoder _encoder({{ .OrdinalName }});
  sender_()->Send(&{{ .Response.HlCodingTable }}, {{ $.ResponseEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .ResponseArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ));
}
    {{- end }}
  {{- end }}
{{- end }}

{{ .SyncProxy.Name }}::{{ .SyncProxy.Name }}(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

{{ .SyncProxy.Name }}::~{{ .SyncProxy.Name }}() = default;

{{- range .Methods }}
  {{- if .HasRequest }}

zx_status_t {{ $.SyncProxy.Name }}::{{ template "SyncRequestMethodSignature" . }} {
  ::fidl::Encoder _encoder({{ .OrdinalName }});
    {{- if .HasResponse }}
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  zx_status_t status_ = proxy_.Call(&{{ .Request.HlCodingTable }}, &{{ .Response.HlCodingTable }}, {{ $.RequestEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .RequestArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ), &response_);
  if (status_ != ZX_OK)
    return status_;
      {{- if .ResponseArgs }}
  ::fidl::Decoder decoder_(std::move(response_));
        {{- range $index, $param := .ResponseArgs }}
  *out_{{ .Name }} = ::fidl::DecodeAs<{{ .Type }}>(&decoder_, {{ .Offset }});
        {{- end }}
      {{- end }}
  return ZX_OK;
    {{- else }}
  return proxy_.Send(&{{ .Request.HlCodingTable }}, {{ $.RequestEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .RequestArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ));
    {{- end }}
}
  {{- end }}
{{- end }}

{{- EndifFuchsia -}}
{{ end }}
`
