<%- assert_locals service -%>
<%- method_service ||= service  -%>
##
# Configuration class for the <%= service.name %> API.
#
# This class represents the configuration for <%= service.name %>,
# providing control over timeouts, retry behavior, logging, transport
# parameters, and other low-level controls. Certain parameters can also be
# applied individually to specific RPCs. See
# {<%= service.client_name_full %>::Configuration::Rpcs}
# for a list of RPCs that can be configured independently.
#
# Configuration can be applied globally to all clients, or to a single client
# on construction.
#
<%- unless method_service.methods.empty? -%>
# # Examples
#
# To modify the global config, setting the timeout for <%= method_service.methods.first.name %>
# to 20 seconds, and all remaining timeouts to 10 seconds:
#
#     <%= service.client_name_full %>.configure do |config|
#       config.timeout = 10.0
#       config.rpcs.<%= method_service.methods.first.name %>.timeout = 20.0
#     end
#
# To apply the above configuration only to a new client:
#
#     client = <%= service.client_name_full %>.new do |config|
#       config.timeout = 10.0
#       config.rpcs.<%= method_service.methods.first.name %>.timeout = 20.0
#     end
#
<%- end -%>
# @!attribute [rw] endpoint
#   The hostname or hostname:port of the service endpoint.
#   Defaults to `<%= service.client_endpoint.inspect %>`.
#   @return [::String]
# @!attribute [rw] credentials
#   Credentials to send with calls. You may provide any of the following types:
#    *  (`String`) The path to a service account key file in JSON format
#    *  (`Hash`) A service account key as a Hash
#    *  (`Google::Auth::Credentials`) A googleauth credentials object
#       (see the [googleauth docs](https://googleapis.dev/ruby/googleauth/latest/index.html))
#    *  (`Signet::OAuth2::Client`) A signet oauth2 client object
#       (see the [signet docs](https://googleapis.dev/ruby/signet/latest/Signet/OAuth2/Client.html))
#    *  (`GRPC::Core::Channel`) a gRPC channel with included credentials
#    *  (`GRPC::Core::ChannelCredentials`) a gRPC credentails object
#    *  (`nil`) indicating no credentials
#   @return [::Object]
# @!attribute [rw] scope
#   The OAuth scopes
#   @return [::Array<::String>]
# @!attribute [rw] lib_name
#   The library name as recorded in instrumentation and logging
#   @return [::String]
# @!attribute [rw] lib_version
#   The library version as recorded in instrumentation and logging
#   @return [::String]
# @!attribute [rw] channel_args
#   Extra parameters passed to the gRPC channel. Note: this is ignored if a
#   `GRPC::Core::Channel` object is provided as the credential.
#   @return [::Hash]
# @!attribute [rw] interceptors
#   An array of interceptors that are run before calls are executed.
#   @return [::Array<::GRPC::ClientInterceptor>]
# @!attribute [rw] timeout
#   The call timeout in seconds.
#   @return [::Numeric]
# @!attribute [rw] metadata
#   Additional gRPC headers to be sent with the call.
#   @return [::Hash{::Symbol=>::String}]
# @!attribute [rw] retry_policy
#   The retry policy. The value is a hash with the following keys:
#    *  `:initial_delay` (*type:* `Numeric`) - The initial delay in seconds.
#    *  `:max_delay` (*type:* `Numeric`) - The max delay in seconds.
#    *  `:multiplier` (*type:* `Numeric`) - The incremental backoff multiplier.
#    *  `:retry_codes` (*type:* `Array<String>`) - The error codes that should
#       trigger a retry.
#   @return [::Hash]
# @!attribute [rw] quota_project
#   A separate project against which to charge quota.
#   @return [::String]
#
class Configuration
  extend ::Gapic::Config

  config_attr :endpoint,      <%= service.client_endpoint.inspect %>, ::String
  config_attr :credentials,   nil do |value|
    allowed = [::String, ::Hash, ::Proc, ::Google::Auth::Credentials, ::Signet::OAuth2::Client, nil]
    allowed += [::GRPC::Core::Channel, ::GRPC::Core::ChannelCredentials] if defined? ::GRPC
    allowed.any? { |klass| klass === value }
  end
  config_attr :scope,         nil, ::String, ::Array, nil
  config_attr :lib_name,      nil, ::String, nil
  config_attr :lib_version,   nil, ::String, nil
  config_attr(:channel_args,  <%= service.config_channel_args.inspect %>, ::Hash, nil)
  config_attr :interceptors,  nil, ::Array, nil
  config_attr :timeout,       nil, ::Numeric, nil
  config_attr :metadata,      nil, ::Hash, nil
  config_attr :retry_policy,  nil, ::Hash, ::Proc, nil
  config_attr :quota_project, nil, ::String, nil

  # @private
  def initialize parent_config = nil
    @parent_config = parent_config unless parent_config.nil?

    yield self if block_given?
  end

  ##
  # Configurations for individual RPCs
  # @return [Rpcs]
  #
  def rpcs
    @rpcs ||= begin
      parent_rpcs = nil
      parent_rpcs = @parent_config.rpcs if defined?(@parent_config) && @parent_config&.respond_to?(:rpcs)
      Rpcs.new parent_rpcs
    end
  end

  ##
  # Configuration RPC class for the <%= service.name %> API.
  #
  # Includes fields providing the configuration for each RPC in this service.
  # Each configuration object is of type `Gapic::Config::Method` and includes
  # the following configuration fields:
  #
  #  *  `timeout` (*type:* `Numeric`) - The call timeout in milliseconds
  #  *  `metadata` (*type:* `Hash{Symbol=>String}`) - Additional gRPC headers
  #  *  `retry_policy (*type:* `Hash`) - The retry policy. The policy fields
  #     include the following keys:
  #      *  `:initial_delay` (*type:* `Numeric`) - The initial delay in seconds.
  #      *  `:max_delay` (*type:* `Numeric`) - The max delay in seconds.
  #      *  `:multiplier` (*type:* `Numeric`) - The incremental backoff multiplier.
  #      *  `:retry_codes` (*type:* `Array<String>`) - The error codes that should
  #         trigger a retry.
  # 
  class Rpcs
  <%- method_service.methods.each do |method| -%>
    ##
    # RPC-specific configuration for `<%= method.name %>`
    # @return [::Gapic::Config::Method]
    #
    attr_reader :<%= method.name %>
  <%- end -%>

    # @private
    def initialize parent_rpcs = nil
      <%- method_service.methods.each do |method| -%>
      <%= method.name %>_config = parent_rpcs&.<%= method.name %> if parent_rpcs&.respond_to? :<%= method.name %>
      @<%= method.name %> = ::Gapic::Config::Method.new <%= method.name %>_config
      <%- end -%>

      yield self if block_given?
    end
  end
end