require_relative "./run.rb"
require_relative "./graphviz.rb"
require "js"

class Promise
  alias orig_value value
  def value
    if Time.now - $start_time > 2.0 # todo, do this from JS?
      raise IogiiError.new("timeout")
    end
    orig_value
  end
end

Document = JS.global[:document]
runbutton = Document.getElementById("runbutton")
Program = Document.getElementById("program")
Prettyprintbox = Document.getElementById("prettyprintbox")
WEB_OUTPUT = Document.getElementById("output")
WEB_STDERR = Document.getElementById("stderr")
Status = Document.getElementById("status")

def append_js(output_str, var, str)
  output_str << str
  var[:value] = output_str.to_js
end

def output(str)
  append_js($ruby_output, WEB_OUTPUT, str)
end

def error_output(str)
  output(str)
end

class String
  def red
    self
  end
end

def set_status(status)
  Status[:innerText] = status.to_js
  JS.eval("return new Promise(r => setTimeout(r, 0))").await
end

def render_graphviz(graph, component)
  JS.eval('d3.select("#' + component + '").graphviz().zoom(false).renderDot('+graph.inspect+');')
end

def run_cb
  set_status("running")
  $ruby_output = ""
  $ruby_stderr = ""

  output(""); error_output("") # reset displays
  JS.eval('d3.selectAll("svg > *").remove();')

  web_inputs = Document.querySelectorAll("#inputsContainer textarea")
  input = web_inputs.to_a.map{|i|i['value'].to_s}
  input = "" if input == [""] # hack to make it consistant with command line use
  pretty_print = Prettyprintbox[:checked].to_s == "true"
  prog = Program[:value].to_s.bytes.map(&:chr).join

  $start_time = Time.now
  begin
    run_and_do_io(prog, input, pretty_print, false,
      ast_cb: -> ast, ast_out_inds {
        ast_graph = ast2viz(ast, ast_out_inds)
        render_graphviz(ast_graph, "ast_graph")
      },
      ir_cb: -> ir2, ir2_out_inds {
        ir_graph = ir2viz(ir2, ir2_out_inds)
        render_graphviz(ir_graph, "ir_graph")
      }
    )
  rescue IogiiError => e
    error_output e.message + "\n"
  rescue => e
    error_output "This is an internal iogii error, please report it!\n"
    raise e
  end
  set_status("")
end

run_cb