<commit_before>InviteRedeemer = Struct.new(:invite, :username, :name) do

  def redeem
    Invite.transaction do
      if invite_was_redeemed?
        process_invitation
        return invited_user
      end
    end

    # If `invite_passthrough_hours` is defined, allow them to re-use the invite link
    # to login again.
    if invite.redeemed_at >= SiteSetting.invite_passthrough_hours.hours.ago
      return invited_user
    end

    nil
  end

  # extracted from User cause it is very specific to invites
  def self.create_user_from_invite(invite, username, name)
    user_exists = User.find_by_email(invite.email)
    return user if user_exists

    if username && User.username_available?(username)
      available_username = username
    else
      available_username = UserNameSuggester.suggest(invite.email)
    end
    available_name = name || available_username

    DiscourseHub.username_operation do
      match, available, suggestion = DiscourseHub.username_match?(available_username, invite.email)
      available_username = suggestion unless match || available
    end

    user = User.new(email: invite.email, username: available_username, name: available_name, active: true, trust_level: SiteSetting.default_invitee_trust_level)
    user.save!

    DiscourseHub.username_operation { DiscourseHub.register_username(username, invite.email) }

    user
  end

  private

  def invited_user
    @invited_user ||= get_invited_user
  end

  def process_invitation
    add_to_private_topics_if_invited
    add_user_to_invited_topics<commit_msg>FIX: Instead of silently failing, assign alternative username when provided username is invalid in disposable invite<commit_after>InviteRedeemer = Struct.new(:invite, :username, :name) do

  def redeem
    Invite.transaction do
      if invite_was_redeemed?
        process_invitation
        return invited_user
      end
    end

    # If `invite_passthrough_hours` is defined, allow them to re-use the invite link
    # to login again.
    if invite.redeemed_at >= SiteSetting.invite_passthrough_hours.hours.ago
      return invited_user
    end

    nil
  end

  # extracted from User cause it is very specific to invites
  def self.create_user_from_invite(invite, username, name)
    user_exists = User.find_by_email(invite.email)
    return user if user_exists

    if username && UsernameValidator.new(username).valid_format? && User.username_available?(username)
      available_username = username
    else
      available_username = UserNameSuggester.suggest(invite.email)
    end
    available_name = name || available_username

    DiscourseHub.username_operation do
      match, available, suggestion = DiscourseHub.username_match?(available_username, invite.email)
      available_username = suggestion unless match || available
    end

    user = User.new(email: invite.email, username: available_username, name: available_name, active: true, trust_level: SiteSetting.default_invitee_trust_level)
    user.save!

    DiscourseHub.username_operation { DiscourseHub.register_username(username, invite.email) }

    user
  end

  private

  def invited_user
    @invited_user ||= get_invited_user
  end

  def process_invitation
    add_to_private_topics_if_invited
    add_user_to_invited_topics
{'fraction_non_alphanumeric': 0.06093080220453154, 'fraction_numerical': 0.0, 'mean_word_length': 3.8471810089020773, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '5804886', 'n_tokens_mistral': 984, 'n_tokens_neox': 940, 'n_words': 235}