<commit_before>class GoogleIntegration::RefreshAccessToken

  class RefreshAccessTokenError < StandardError; end

  class NoRefreshTokenError < RefreshAccessTokenError
    def message
      "No existing Google Refresh Token available to submit"
    end
  end

  class TokenTooOldToRefreshError < RefreshAccessTokenError
    def message
      "Existing Google Access Token is too old to refresh"
    end
  end

  class FailedToRefreshTokenError < RefreshAccessTokenError; end

  class FailedToSaveRefreshedTokenError < RefreshAccessTokenError; end

  TOKEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'

  def initialize(user, http_client = nil)
    @user        = user
    @http_client = http_client || HTTParty
  end

  def refresh
    if should_refresh?
      raise NoRefreshTokenError if !current_credentials&.refresh_token
      # According to Google documentation, refresh tokens older than
      # 6 months can not be refreshed:
      # https://developers.google.com/identity/protocols/OAuth2#expiration
      raise TokenTooOldToRefreshError if token_too_old_to_refresh?
      handle_response(make_request)
    else
      current_credentials
    end
  end

  private

  def make_request
    @http_client.post(TOKEN_ENDPOINT, refresh_token_options)
  end

  def handle_response(response)
    if response.code == 200
      store_credentials(response)
    else
      msg = "Non-200 response when attempting to refresh access token: '#{response.parsed_response['error']}'"
      raise FailedToRefreshTokenError, msg
    end
  end

  def store_credentials(response)
    data       = response.parsed_response
    attributes = parse_attributes(data)

    if current_credentials.update(attributes)
      current_credentials.reload
    else
      msg = "Failed to save updated access token: '#{current_credentials.errors.messages}'"<commit_msg>when refresh access token fails, delete current_credentials so that user is forced to login again<commit_after>class GoogleIntegration::RefreshAccessToken

  class RefreshAccessTokenError < StandardError; end

  class NoRefreshTokenError < RefreshAccessTokenError
    def message
      "No existing Google Refresh Token available to submit"
    end
  end

  class TokenTooOldToRefreshError < RefreshAccessTokenError
    def message
      "Existing Google Access Token is too old to refresh"
    end
  end

  class FailedToRefreshTokenError < RefreshAccessTokenError; end

  class FailedToSaveRefreshedTokenError < RefreshAccessTokenError; end

  TOKEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'

  def initialize(user, http_client = nil)
    @user        = user
    @http_client = http_client || HTTParty
  end

  def refresh
    if should_refresh?
      raise NoRefreshTokenError if !current_credentials&.refresh_token
      # According to Google documentation, refresh tokens older than
      # 6 months can not be refreshed:
      # https://developers.google.com/identity/protocols/OAuth2#expiration
      raise TokenTooOldToRefreshError if token_too_old_to_refresh?
      handle_response(make_request)
    else
      current_credentials
    end
  end

  private

  def make_request
    @http_client.post(TOKEN_ENDPOINT, refresh_token_options)
  end

  def handle_response(response)
    if response.code == 200
      store_credentials(response)
    else
      msg = "Non-200 response when attempting to refresh access token: '#{response.parsed_response['error']}'"
      # delete current_credentials so that user is forced to login again
      current_credentials.destroy!
      raise FailedToRefreshTokenError, msg
    end
  end

  def store_credentials(response)
    data       = response.parsed_response
    attributes = parse_attributes(data)

    if current_credentials.update(attributes)
      current_credentials.reload
    else
      msg = "Failed to save updated access token: '#{current_credentials.errors.messages}'"
{'fraction_non_alphanumeric': 0.05701078582434515, 'fraction_numerical': 0.004622496147919877, 'mean_word_length': 3.75, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6027605', 'n_tokens_mistral': 1098, 'n_tokens_neox': 1057, 'n_words': 294}