module Jekyll
  module Filters
    module GroupingFilters
      # Group an array of items by a property
      #
      # input - the inputted Enumerable
      # property - the property
      #
      # Returns an array of Hashes, each looking something like this:
      #  {"name"  => "larry"
      #   "items" => [...] } # all the items where `property` == "larry"
      def group_by(input, property)
        if groupable?(input)
          groups = input.group_by { |item| item_property(item, property).to_s }
          grouped_array(groups)
        else
          input
        end
      end

      # Group an array of items by an expression
      #
      # input - the object array
      # variable - the variable to assign each item to in the expression
      # expression -a Liquid comparison expression passed in as a string
      #
      # Returns the filtered array of objects
      def group_by_exp(input, variable, expression)
        return input unless groupable?(input)

        parsed_expr = parse_expression(expression)
        @context.stack do
          groups = input.group_by do |item|
            @context[variable] = item
            parsed_expr.render(@context)
          end
          grouped_array(groups)
        end
      end

      private
      def parse_expression(str)
        Liquid::Variable.new(str, Liquid::ParseContext.new)
      end

      private
      def groupable?(element)
        element.respond_to?(:group_by)
      end

      private
      def grouped_array(groups)
        groups.each_with_object([]) do |item, array|
          array << {
            "name"  => item.first,
            "items" => item.last,
            "size"  => item.last.size,
          }
        end
      end
    end
  end
end
