<commit_before># Finds an address based on the data provided
# Can take any combination of an email String, Customer or Spree::User as args
# The #bill_address and #ship_address methods automatically return matched addresses
# according to this order: customer addresses, user addresses, addresses from
# completed orders with an email that matches the email string provided.
module OpenFoodNetwork
  class AddressFinder
    attr_accessor :email, :user, :customer

    def initialize(*args)
      args.each do |arg|
        case arg
        when String
          @email = arg unless @email
        when Customer
          @customer = arg unless @customer
        when Spree::User
          @user = arg unless @user
        end
      end
    end

    def bill_address
      customer_preferred_bill_address || user_preferred_bill_address || fallback_bill_address
    end

    def ship_address
      customer_preferred_ship_address || user_preferred_ship_address || fallback_ship_address
    end

    private

    def customer_preferred_bill_address
      customer.andand.bill_address
    end

    def customer_preferred_ship_address
      customer.andand.ship_address
    end

    def user_preferred_bill_address
      user.andand.bill_address
    end

    def user_preferred_ship_address
      user.andand.ship_address
    end

    def fallback_bill_address
      last_used_bill_address.andand.clone || Spree::Address.default
    end

    def fallback_ship_address
      last_used_ship_address.andand.clone || Spree::Address.default
    end

    def last_used_bill_address
      return nil unless allow_search_by_email?
      Spree::Order.joins(:bill_address).order('id DESC')
        .complete.where(email: email)
        .first.andand.bill_address
    end

    def last_used_ship_address
      return nil unless allow_search_by_email?
      Spree::Order.complete.joins(:ship_address, :shipping_method).order('id DESC')
        .where(email: email, spree_shipping_methods: { require_ship_address: true })
        .first.andand.ship_address
    end

    # Only allow search for address by email if a customer or user with the
    # same address has been provided, otherwise we are providing access to
    # addresses with only an email address, which could be problematic.
    # Assumption: front-end users can't ask this library for an address using
    # a customer or user other than themselves...
    def allow_search_by_email?
      return false unless email.present? && (user.present? || customer.present?)
      return false unless email == customer.andand.email || email == user.andand.email
      true
    end
  end
end
<commit_msg>Reduce congnitive complexity of AddressFinder<commit_after># Finds an address based on the data provided
# Can take any combination of an email String, Customer or Spree::User as args
# The #bill_address and #ship_address methods automatically return matched addresses
# according to this order: customer addresses, user addresses, addresses from
# completed orders with an email that matches the email string provided.

module OpenFoodNetwork
  class AddressFinder
    attr_reader :email, :user, :customer

    def initialize(*args)
      args.each do |arg|
        type = types[arg.class]
        next unless type
        send("#{type}=", arg)
      end
    end

    def bill_address
      customer_preferred_bill_address || user_preferred_bill_address || fallback_bill_address
    end

    def ship_address
      customer_preferred_ship_address || user_preferred_ship_address || fallback_ship_address
    end

    private

    def types
      {
        String      => "email",
        Customer    => "customer",
        Spree::User => "user"
      }
    end

    def email=(arg)
      @email ||= arg
    end

    def customer=(arg)
      @customer ||= arg
    end

    def user=(arg)
      @user ||= arg
    end

    def customer_preferred_bill_address
      customer.andand.bill_address
    end

    def customer_preferred_ship_address
      customer.andand.ship_address
    end

    def user_preferred_bill_address
      user.andand.bill_address
    end

    def user_preferred_ship_address
      user.andand.ship_address
    end

    def fallback_bill_address
      last_used_bill_address.andand.clone || Spree::Address.default
    end

    def fallback_ship_address
      last_used_ship_address.andand.clone || Spree::Address.default
    end

    def last_used_bill_address
      return nil unless allow_search_by_email?
      Spree::Order.joins(:bill_address).order('id DESC')
        .complete.where(email: email)
        .first.andand.bill_address
    end

    def last_used_ship_address
      return nil unless allow_search_by_email?
      Spree::Order.complete.joins(:ship_address, :shipping_method).order('id DESC')
        .where(email: email, spree_shipping_methods: { require_ship_address: true })
        .first.andand.ship_address
    end

    # Only allow search for address by email if a customer or user with the
    # same address has been provided, otherwise we are providing access to
    # addresses with only an email address, which could be problematic.
    # Assumption: front-end users can't ask this library for an address using
    # a customer or user other than themselves...
    def allow_search_by_email?
      email.present? && email_matches_customer_or_user?
    end

    def email_matches_customer_or_user?
      email == customer.andand.email || email == user.andand.email
    end
  end
end

{'fraction_non_alphanumeric': 0.0623400365630713, 'fraction_numerical': 0.0, 'mean_word_length': 3.058605341246291, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, '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': '2543275', 'n_tokens_mistral': 1575, 'n_tokens_neox': 1511, 'n_words': 463}