module EasyPatch

  module ActsAsActivityProviderMethodsPatch

    def self.included(base)
      base.send(:include, ClassMethods)

      base.class_eval do

      end
    end

    module ClassMethods
      def easy_event_type_name(event_type = nil)
        event_type || self.name.underscore.pluralize
      end

      def easy_find_events(event_type, user, from, to, options)
        provider_options = activity_provider_options[event_type]
        options[:update_timestamp] = activity_provider_options[:update_timestamp] || provider_options[:timestamp]
        easy_provider_options = activity_provider_options[:easy_activity_options][event_type] if activity_provider_options[:easy_activity_options]
        raise "#{self.name} can not provide #{event_type} events." if provider_options.nil?

        scope = (provider_options[:scope] || self)

        if from && to
          update_timestamp = provider_options[:timestamp]
          update_timestamp = options[:update_timestamp] if options[:display_updated]
          scope = scope.where("#{update_timestamp} BETWEEN ? AND ?", from, to)
        end

        if options[:author]
          return [] if provider_options[:author_key].nil?
          scope = scope.where("#{provider_options[:author_key]} = ?", options[:author].id)
        end

        if options[:user]
          return [] if easy_provider_options.nil? || easy_provider_options[:user_scope].nil?
          scope = easy_provider_options[:user_scope].call(options[:user], scope)
        end

        if options[:project_ids]
          if self.respond_to?(:easy_activity_custom_project_scope)
            scope = self.easy_activity_custom_project_scope(scope, options, event_type)
          elsif self.column_names.include?('project_id')
            scope = scope.where(:project_id => options[:project_ids])
          end
        end

        # if options[:limit]
        #   # id and creation time should be in same order in most cases
        #   scope = scope.reorder("#{table_name}.id DESC").limit(options[:limit])
        # end

        if provider_options.has_key?(:permission)
          scope = scope.where(Project.allowed_to_condition(user, provider_options[:permission] || :view_project, options))
        elsif respond_to?(:visible)
          scope = scope.visible(user, options)
        else
          ActiveSupport::Deprecation.warn "acts_as_activity_provider with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
          scope = scope.where(Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym, options))
        end

        if self.respond_to?(:user_readable_options)
          arel_table = self.arel_table

          self_table = self.arel_table
          eure_table = EasyUserReadEntity.arel_table
          j = self_table.join(eure_table, Arel::Nodes::OuterJoin).
                           on(eure_table[:user_id].eq(user.id).and(self_table[:id].eq(eure_table[:entity_id])).and(eure_table[:entity_type].eq(self.name))).
                           join_sources
          scope = scope.joins(j).where(eure_table[:user_id].eq(nil))

          #scope = scope.includes(:user_read_records)
          #eure_table = EasyUserReadEntity.arel_table
          #scope = scope.where(scope.where(eure_table[:user_id].eq(user.id)).exists.not)
          #scope = scope.includes(:user_read_records).where(EasyUserReadEntity.arel_table[:user_id].not_eq(user.id))
        end

        scope.uniq
      end
    end

  end
end
EasyExtensions::PatchManager.register_patch_to_be_first 'Redmine::Acts::ActivityProvider::InstanceMethods::ClassMethods', 'EasyPatch::ActsAsActivityProviderMethodsPatch', :first => true
