require 'revdispatch'

# to run this through valgrind run the server outside of this script
# i run this: valgrind --leak-check=full ~/project/ruby-valgrind-env/bin/ruby test.rb r
pid = nil
running_ebb_here = (ARGV[0] != 'r' and !`uname`.grep(/darwin/i))
if running_ebb_here 
  puts "starting ebb in this process"
  pid = fork do
    require 'server'
    start_test_server
  end
end

require 'ostruct'

# NOTE: we define this part in ruby to make sure other ruby threads can execute while we wait
class Evdispatch::Loop
  def response(id)
    while wait_for_response( id, 1, 0 )
      res = response_for( id )
      break if res
    end
    res = response_for( id ) unless res
    res
  end
end

def request_bytes_from( d, base, amount, range )
  ids = []
  amount.times do|i|
    am = rand( range )
    ids << d.request_http( base + "bytes/#{am}/" )
  end
  ids
end

def request_delay_from( d, base, amount, delay )
  ids = []
  amount.times do|i|
    am = rand( delay )
    ids << d.request_http( base + "delay/#{delay}/" )
  end
  ids
end

def run_trial

  d = Evdispatch::Loop.new

  # start the event loop thread
  d.start


  timer = Time.now
  # send a dispatch http request and store a handle to the request
  google_id = d.request_http("http://www.google.com/")

  # do some processing and later on check for the response
  response = d.response( google_id )
  puts "Requested: #{response[0]} in #{Time.now - timer} seconds"

  ebbbase = "http://127.0.0.1:4044/"
  timer = Time.now
  ids = request_bytes_from( d, ebbbase, 400, 10000 )
  #ids += request_delay_from( d, ebbbase, 100, 1 )

  # wait for each response
  puts "expecting #{ids.size} responses..."
  ids.each do|id|
    response = d.response( id )
    #puts response[:name]
    ObjectSpace.garbage_collect
  end

  puts "recieved #{ids.size} responses in #{Time.now - timer} seconds"

  # sometime later you can stop the event loop
  d.stop
end

begin
  sleep 1 if running_ebb_here

  ObjectSpace.garbage_collect

  count = ObjectSpace.each_object { }
  puts "Starting Total objects: #{count}"

  begin
    run_trial
  rescue => e
    puts e.message, e.backtrace
  end


  count = ObjectSpace.each_object { }
  puts "Final Total objects: #{count}"
  count = nil
  ObjectSpace.garbage_collect
end

count = ObjectSpace.each_object { }
puts "After garbage collection objects: #{count}"
Process.kill('HUP', pid) if running_ebb_here