require "./run.rb"
require "./test/collect_tests.rb"
require 'stringio'

def runtest(prog, found, input: "", len: 1000, no_pp: false)

  ir3, ir3_ind = gen_graph(prog, StringIO.new(input), pp_sep: no_pp ? nil : " ")
  promises = make_promises(ir3)
  output = promises[ir3_ind]
  while !output.empty && len > 0
    len -= 1
    found << to_eager_str([output.value[0], Null])
    output = output.value[1]
  end
end

tests = collect_tests

pass = 0
tests.each{|test|
  $stderr = StringIO.new

  prog, expected, from, input, no_pp = *test
  input ||= ""
  expected = "" if !expected
  expected.strip!
  prog.strip!
  begin
    found = ""
    if expected =~ /\.\.\.$/
      runtest(prog, found, input: input, len: $`.size, no_pp: no_pp)
      expected = $`
    elsif expected =~ /\.\.\./
      runtest(prog, found, input: input, no_pp: no_pp)
      found = found[0,$`.size]+"..."+found[-$'.size-1..-1]
    else
      runtest(prog, found, input: input, no_pp: no_pp)
    end
    found.rstrip!
    errored = false
  rescue Exception
    errored = $!
    found << $!.message.gsub(IogiiError.new("").message, "ERROR: ").lines.map(&:rstrip).join("\n")
    if expected['...']
      found = found[0,expected.index("...")] + "..."
    end
  end
  found += "\n"+$stderr.string if expected != "Overflow" # don't add it for this because ruby makes a weird warning
  found.chomp!
  expected.gsub!("WARNING: ","WARNING: ".red)

  if expected == "RANK ERROR" && found[/arg\d? rank too low/]
  elsif found != expected
    STDERR.puts "FAIL: #{from}"
    STDERR.puts prog
    STDERR.puts "expected:"
    STDERR.puts expected
    STDERR.puts "found:"
    STDERR.puts found
    $stderr = STDERR
    raise errored if errored
    exit(1)
  end

  pass += 1
}

puts "PASS #{pass} tests"
