<%- assert_locals service -%>
<% @requires = capture do %>
<%= render partial: "service/client/requires", locals: { service: service} -%>
require "<%= service.proto_service_require %>"
<% end %>
##
# Client for the <%= service.name %> service.
#
<%- if service.doc_description -%>
<%= indent service.doc_description, "# " %>
#
<%- end -%>
class <%= service.client_name %>
<%- if service.paths? -%>
  include <%= service.paths_name %>

<%- end -%>
  # @private
  attr_reader :<%= service.stub_name %>

  ##
  # Configure the <%= service.name %> <%= service.client_name %> class.
  #
  # See {<%= service.client_name_full %>::Configuration}
  # for a description of the configuration fields.
  #
  # ## Example
  #
  # To modify the configuration for all <%= service.name %> clients:
  #
  #     <%= service.client_name_full %>.configure do |config|
  #       config.timeout = 10.0
  #     end
  #
  # @yield [config] Configure the <%= service.client_name %> client.
  # @yieldparam config [<%= service.client_name %>::Configuration]
  #
  # @return [<%= service.client_name %>::Configuration]
  #
  def self.configure
<%= indent render(partial: "service/client/self_configure", locals: { service: service }), 4 %>
  end

  ##
  # Configure the <%= service.name %> <%= service.client_name %> instance.
  #
  # The configuration is set to the derived mode, meaning that values can be changed,
  # but structural changes (adding new fields, etc.) are not allowed. Structural changes
  # should be made on {<%= service.client_name %>.configure}.
  #
  # See {<%= service.client_name_full %>::Configuration}
  # for a description of the configuration fields.
  #
  # @yield [config] Configure the <%= service.client_name %> client.
  # @yieldparam config [<%= service.client_name %>::Configuration]
  #
  # @return [<%= service.client_name %>::Configuration]
  #
  def configure
    yield @config if block_given?
    @config
  end

  ##
  # Create a new <%= service.name %> client object.
  #
  # ## Examples
  #
  # To create a new <%= service.name %> client with the default
  # configuration:
  #
  #     client = <%= service.client_name_full %>.new
  #
  # To create a new <%= service.name %> client with a custom
  # configuration:
  #
  #     client = <%= service.client_name_full %>.new do |config|
  #       config.timeout = 10.0
  #     end
  #
  # @yield [config] Configure the <%= service.name %> client.
  # @yieldparam config [<%= service.client_name %>::Configuration]
  #
  def initialize
    # These require statements are intentionally placed here to initialize
    # the gRPC module only when it's required.
    # See https://github.com/googleapis/toolkit/issues/446
    require "gapic/grpc"
    require "<%= service.proto_services_require %>"

    # Create the configuration object
    @config = Configuration.new <%= service.client_name %>.configure

    # Yield the configuration if needed
    yield @config if block_given?

    # Create credentials
    credentials = @config.credentials
    <%- unless service.generic_endpoint? -%>
    credentials ||= Credentials.default scope: @config.scope
    if credentials.is_a?(String) || credentials.is_a?(Hash)
      credentials = Credentials.new credentials, scope: @config.scope
    end
    <%- end -%>
    @quota_project_id = @config.quota_project
    @quota_project_id ||= credentials.quota_project_id if credentials.respond_to? :quota_project_id

    <%- if service.lro? -%>
    <%= service.lro_client_ivar %> = <%= service.operations_name %>.new do |config|
      config.credentials = credentials
      config.endpoint = @config.endpoint
    end

    <%- end -%>
    @<%= service.stub_name %> = ::Gapic::ServiceStub.new(
      <%= service.proto_service_stub_name_full %>,
      credentials:  credentials,
      endpoint:     @config.endpoint,
      channel_args: @config.channel_args,
      interceptors: @config.interceptors
    )
  end

<%- if service.lro? -%>
  ##
  # Get the associated client for long-running operations.
  #
  # @return [<%= service.operations_name_full %>]
  #
  attr_reader :<%= service.lro_client_var %>

<%- end -%>
  # Service calls
  <%- service.methods.each do |method| -%>

  <%= indent_tail render(partial: "service/client/method/def", locals: { method: method }), 2 %>
  <%- end %>

  <%= indent_tail render(partial: "service/client/config", locals: { service: service }), 2 %>
end