module Urbivore
  module Outputs
  end

  class Processor
    include Decorum::Decorations
    include Urbivore::Outputs

    class << self
      alias_method :output, :decorators
      alias_method :outputs, :output
      
      attr_reader :preprocessor

      def preprocess(&block)
        @preprocessor = block
      end
    end

    attr_reader :channel, :options

    def initialize(channel, options = {})
      @channel  = channel
      @options  = options

      load_decorators_from_class

      # reproduction of logic in Decorum::Decorations... should see if there's
      # a good way to DRY this
      if options[:outputs].is_a?(Array)
        options[:outputs].each do |arg|
          if arg.ancestors.include?(Decorum::Decorator) || arg.is_a?(Hash)
            next if arg.is_a?(Hash)
            next_arg     = options[:outputs][options[:outputs].index(arg) + 1]
            deco_options = next_arg.is_a?(Hash) ? next_arg : {}
            decorate(arg, deco_options)
          else
            raise ArgumentError.new("invalid output option #{arg}")
          end
        end
      end

      unless is_decorated?
        # make a note of this in the Urbivore log...
        decorate(Outputs::Null)
      end
    end

    def process_message(message)
      _process(message)
    end

    def call_shutdown
      _shutdown
    end

    def pre
      self.class.preprocessor
    end
  end
end
