<commit_before>module ActivityNotification
  # Notifiable implementation included in notifiable model to be notified, like comments or any other user activities.
  module Notifiable
    extend ActiveSupport::Concern
    # include PolymorphicHelpers to resolve string extentions
    include ActivityNotification::PolymorphicHelpers

    included do
      include Common
      include Association
      include ActionDispatch::Routing::PolymorphicRoutes
      include Rails.application.routes.url_helpers

      # Has many notification instances for this notifiable.
      # Dependency for these notifications can be overriden from acts_as_notifiable.
      # @scope instance
      # @return [Array<Notificaion>, Mongoid::Criteria<Notificaion>] Array or database query of notifications for this notifiable
      has_many_records :generated_notifications_as_notifiable,
        class_name: "::ActivityNotification::Notification",
        as: :notifiable

      class_attribute  :_notification_targets,
                       :_notification_group,
                       :_notification_group_expiry_delay,
                       :_notifier,
                       :_notification_parameters,
                       :_notification_email_allowed,
                       :_notifiable_path,
                       :_printable_notifiable_name,
                       :_optional_targets
      set_notifiable_class_defaults
    end

    # Returns default_url_options for polymorphic_path.
    # @return [Hash] Rails.application.routes.default_url_options
    def default_url_options
      Rails.application.routes.default_url_options
    end

    class_methods do
      # Checks if the model includes notifiable and notifiable methods are available.
      # @return [Boolean] Always true
      def available_as_notifiable?
        true
      end

      # Sets default values to notifiable class fields.
      # @return [NilClass] nil
      def set_notifiable_class_defaults
        self._notification_targets            = {}
        self._notification_group              = {}
        self._notification_group_expiry_delay = {}
        self._notifier                        = {}
        self._notification_parameters         = {}
        self._notification_email_allowed      = {}
        self._notifiable_path                 = {}
        self._printable_notifiable_name       = {}
        self._optional_targets                = {}
        nil
      end
    end

    # Returns notification targets from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [Hash] options Options for notifications
    # @option options [String]                  :key                      (notifiable.default_notification_key) Key of the notification
    # @option options [Hash]                    :parameters               ({})                                  Additional parameters of the notifications
    # @return [Array<Notificaion> | ActiveRecord_AssociationRelation<Notificaion>] Array or database query of the notification targets
    def notification_targets(target_type, options = {})
      target_typed_method_name = "notification_#{cast_to_resources_name(target_type)}"
      resolved_parameter = resolve_parameter(
        target_typed_method_name,
        _notification_targets[cast_to_resources_sym(target_type)],
        nil,
        options)
      unless resolved_parameter
        raise NotImplementedError, "You have to implement #{self.class}##{target_typed_method_name} "\
                                   "or set :targets in acts_as_notifiable"
      end
      resolved_parameter
    end

    # Returns group unit of the notifications from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Object] Group unit of the notifications
    def notification_group(target_type, key = nil)
      resolve_parameter(
        "notification_group_for_#{cast_to_resources_name(target_type)}",
        _notification_group[cast_to_resources_sym(target_type)],
        nil,
        key)
    end

    # Returns group expiry period of the notifications from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Object] Group expiry period of the notifications
    def notification_group_expiry_delay(target_type, key = nil)
      resolve_parameter(
        "notification_group_expiry_delay_for_#{cast_to_resources_name(target_type)}",
        _notification_group_expiry_delay[cast_to_resources_sym(target_type)],
        nil,
        key)
    end

    # Returns additional notification parameters from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Hash] Additional notification parameters
    def notification_parameters(target_type, key = nil)
      resolve_parameter(
        "notification_parameters_for_#{cast_to_resources_name(target_type)}",
        _notification_parameters[cast_to_resources_sym(target_type)],
        {},
        key)
    end

    # Returns notifier of the notification from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Object] Notifier of the notification
    def notifier(target_type, key = nil)
      resolve_parameter(
        "notifier_for_#{cast_to_resources_name(target_type)}",
        _notifier[cast_to_resources_sym(target_type)],
        nil,
        key)
    end

    # Returns if sending notification email is allowed for the notifiable from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [Object] target Target instance to notify
    # @param [String] key Key of the notification
    # @return [Boolean] If sending notification email is allowed for the notifiable
    def notification_email_allowed?(target, key = nil)
      resolve_parameter(
        "notification_email_allowed_for_#{cast_to_resources_name(target.class)}?",
        _notification_email_allowed[cast_to_resources_sym(target.class)],
        ActivityNotification.config.email_enabled,
        target, key)
    end

    # Returns notifiable_path to move after opening notification from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [String] Notifiable path URL to move after opening notification
    def notifiable_path(target_type, key = nil)
      resolved_parameter = resolve_parameter(
        "notifiable_path_for_#{cast_to_resources_name(target_type)}",
        _notifiable_path[cast_to_resources_sym(target_type)],
        nil,
        key)
      unless resolved_parameter
        begin
          resolved_parameter = polymorphic_path(self)
        rescue NoMethodError, ActionController::UrlGenerationError
          raise NotImplementedError, "You have to implement #{self.class}##{__method__}, "\
                                     "set :notifiable_path in acts_as_notifiable or "\
                                     "set polymorphic_path routing for #{self.class}"
        end
      end
      resolved_parameter
    end

    # Returns printable notifiable model name to show in view or email.
    # @return [String] Printable notifiable model name<commit_msg>Fix Notifiable#notifiable_path to work when it is defined in a superclass - #45<commit_after>module ActivityNotification
  # Notifiable implementation included in notifiable model to be notified, like comments or any other user activities.
  module Notifiable
    extend ActiveSupport::Concern
    # include PolymorphicHelpers to resolve string extentions
    include ActivityNotification::PolymorphicHelpers

    included do
      include Common
      include Association
      include ActionDispatch::Routing::PolymorphicRoutes
      include Rails.application.routes.url_helpers

      # Has many notification instances for this notifiable.
      # Dependency for these notifications can be overriden from acts_as_notifiable.
      # @scope instance
      # @return [Array<Notificaion>, Mongoid::Criteria<Notificaion>] Array or database query of notifications for this notifiable
      has_many_records :generated_notifications_as_notifiable,
        class_name: "::ActivityNotification::Notification",
        as: :notifiable

      class_attribute  :_notification_targets,
                       :_notification_group,
                       :_notification_group_expiry_delay,
                       :_notifier,
                       :_notification_parameters,
                       :_notification_email_allowed,
                       :_notifiable_path,
                       :_printable_notifiable_name,
                       :_optional_targets
      set_notifiable_class_defaults
    end

    # Returns default_url_options for polymorphic_path.
    # @return [Hash] Rails.application.routes.default_url_options
    def default_url_options
      Rails.application.routes.default_url_options
    end

    class_methods do
      # Checks if the model includes notifiable and notifiable methods are available.
      # @return [Boolean] Always true
      def available_as_notifiable?
        true
      end

      # Sets default values to notifiable class fields.
      # @return [NilClass] nil
      def set_notifiable_class_defaults
        self._notification_targets            = {}
        self._notification_group              = {}
        self._notification_group_expiry_delay = {}
        self._notifier                        = {}
        self._notification_parameters         = {}
        self._notification_email_allowed      = {}
        self._notifiable_path                 = {}
        self._printable_notifiable_name       = {}
        self._optional_targets                = {}
        nil
      end
    end

    # Returns notification targets from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [Hash] options Options for notifications
    # @option options [String]                  :key                      (notifiable.default_notification_key) Key of the notification
    # @option options [Hash]                    :parameters               ({})                                  Additional parameters of the notifications
    # @return [Array<Notificaion> | ActiveRecord_AssociationRelation<Notificaion>] Array or database query of the notification targets
    def notification_targets(target_type, options = {})
      target_typed_method_name = "notification_#{cast_to_resources_name(target_type)}"
      resolved_parameter = resolve_parameter(
        target_typed_method_name,
        _notification_targets[cast_to_resources_sym(target_type)],
        nil,
        options)
      unless resolved_parameter
        raise NotImplementedError, "You have to implement #{self.class}##{target_typed_method_name} "\
                                   "or set :targets in acts_as_notifiable"
      end
      resolved_parameter
    end

    # Returns group unit of the notifications from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Object] Group unit of the notifications
    def notification_group(target_type, key = nil)
      resolve_parameter(
        "notification_group_for_#{cast_to_resources_name(target_type)}",
        _notification_group[cast_to_resources_sym(target_type)],
        nil,
        key)
    end

    # Returns group expiry period of the notifications from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Object] Group expiry period of the notifications
    def notification_group_expiry_delay(target_type, key = nil)
      resolve_parameter(
        "notification_group_expiry_delay_for_#{cast_to_resources_name(target_type)}",
        _notification_group_expiry_delay[cast_to_resources_sym(target_type)],
        nil,
        key)
    end

    # Returns additional notification parameters from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Hash] Additional notification parameters
    def notification_parameters(target_type, key = nil)
      resolve_parameter(
        "notification_parameters_for_#{cast_to_resources_name(target_type)}",
        _notification_parameters[cast_to_resources_sym(target_type)],
        {},
        key)
    end

    # Returns notifier of the notification from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [Object] Notifier of the notification
    def notifier(target_type, key = nil)
      resolve_parameter(
        "notifier_for_#{cast_to_resources_name(target_type)}",
        _notifier[cast_to_resources_sym(target_type)],
        nil,
        key)
    end

    # Returns if sending notification email is allowed for the notifiable from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [Object] target Target instance to notify
    # @param [String] key Key of the notification
    # @return [Boolean] If sending notification email is allowed for the notifiable
    def notification_email_allowed?(target, key = nil)
      resolve_parameter(
        "notification_email_allowed_for_#{cast_to_resources_name(target.class)}?",
        _notification_email_allowed[cast_to_resources_sym(target.class)],
        ActivityNotification.config.email_enabled,
        target, key)
    end

    # Returns notifiable_path to move after opening notification from configured field or overriden method.
    # This method is able to be overriden.
    #
    # @param [String] target_type Target type to notify
    # @param [String] key Key of the notification
    # @return [String] Notifiable path URL to move after opening notification
    def notifiable_path(target_type, key = nil)
      resolved_parameter = resolve_parameter(
        "notifiable_path_for_#{cast_to_resources_name(target_type)}",
        _notifiable_path[cast_to_resources_sym(target_type)],
        nil,
        key)
      unless resolved_parameter
        begin
          resolved_parameter = defined?(super) ? super : polymorphic_path(self)
        rescue NoMethodError, ActionController::UrlGenerationError
          raise NotImplementedError, "You have to implement #{self.class}##{__method__}, "\
                                     "set :notifiable_path in acts_as_notifiable or "\
                                     "set polymorphic_path routing for #{self.class}"
        end
      end
      resolved_parameter
    end

    # Returns printable notifiable model name to show in view or email.
    # @return [String] Printable notifiable model name
{'fraction_non_alphanumeric': 0.06032069228811402, 'fraction_numerical': 0.00012725884448969204, 'mean_word_length': 2.7120925838450636, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3628778', 'n_tokens_mistral': 4057, 'n_tokens_neox': 3916, 'n_words': 1180}