module Matchers
  class BroadcastToSupplier
    class TestBroadcaster
      attr_reader :broadcasts

      def initialize
        @broadcasts = []
      end

      def broadcast(object)
        self.broadcasts << object
      end
    end

    def initialize(supplier_id)
      @supplier_id = supplier_id
    end

    def matches?(block)
      old_broadcaster = Qwaiter.broadcaster
      test_broadcaster = TestBroadcaster.new
      Qwaiter.broadcaster = test_broadcaster
      block.call
      Qwaiter.broadcaster = old_broadcaster

      relevant_broadcasts = test_broadcaster.broadcasts.select{|b| b[:channel] =~ /^\/supplier\/#{@supplier_id}/ && b[:data][:event] == @message}
      @failure_debug_content = "was #{relevant_broadcasts.map{|b| b[:data][:data].inspect}.join(" and ")}"
      relevant_broadcasts.any?{|b| @target_object === b[:data][:data] }
    end

    def message(msg)
      @message = msg
      self
    end

    def with(target_object)
      @target_object = target_object
      self
    end

    def failure_message
      "supplier #{@supplier_id} did not receive broadcast #{@message} with #{@target_object.inspect} #{@failure_debug_content}"
    end
    def supports_block_expectations?; true; end
  end

  def broadcast_to_supplier(*args, &block)
    BroadcastToSupplier.new(*args, &block)
  end
end
