module Google::Auth::BaseClient

def apply a_hash, opts = {}

Returns a clone of a_hash updated with the authentication token
def apply a_hash, opts = {}
  a_copy = a_hash.clone
  apply! a_copy, opts
  a_copy
end

def apply! a_hash, opts = {}

Updates a_hash updated with the authentication token
def apply! a_hash, opts = {}
  # fetch the access token there is currently not one, or if the client
  # has expired
  fetch_access_token! opts if needs_access_token?
  token = send token_type
  a_hash[AUTH_METADATA_KEY] = "Bearer #{token}"
  logger&.debug do
    hash = Digest::SHA256.hexdigest token
    Google::Logging::Message.from message: "Sending auth token. (sha256:#{hash})"
  end
  a_hash[AUTH_METADATA_KEY]
end

def expires_within?

def expires_within?
  raise NoMethodError, "expires_within? not implemented"
end

def fetch_access_token!

def fetch_access_token!
  raise NoMethodError, "fetch_access_token! not implemented"
end

def needs_access_token?

Whether the id_token or access_token is missing or about to expire.
def needs_access_token?
  send(token_type).nil? || expires_within?(60)
end

def notify_refresh_listeners

def notify_refresh_listeners
  listeners = defined?(@refresh_listeners) ? @refresh_listeners : []
  listeners.each do |block|
    block.call self
  end
end

def on_refresh &block

def on_refresh &block
  @refresh_listeners = [] unless defined? @refresh_listeners
  @refresh_listeners << block
end

def token_type

def token_type
  raise NoMethodError, "token_type not implemented"
end

def updater_proc

a closure
Returns a reference to the #apply method, suitable for passing as
def updater_proc
  proc { |a_hash, opts = {}| apply a_hash, opts }
end