#!/usr/bin/env ruby

require 'rbbt/util/simpleopt'
require 'rbbt/workflow'
require 'rbbt/workflow/usage'

def run_task(workflow, task, name)
  Log.info "Running example #{Log.color :magenta, workflow.to_s}##{Log.color :yellow, task} -- #{Log.color :cyan, name}"

  example_dir = workflow.libdir.examples[task][name].find
  Log.debug "Using #{example_dir}"

  ARGV.replace([workflow.to_s, task, '--load_inputs', example_dir, '--jobname', name,'-pf'] + $saved_args)

  path = nil
  success = nil
  TmpFile.with_file do |res|
    Open.open(res, :mode => 'w') do |file|
      @pid = Process.fork{
        STDOUT.reopen res
        load Rbbt.share.rbbt_commands.workflow.task.find
      }
      Signal.trap(:INT) do
        begin
          Process.kill "INT", @pid
        ensure
          Kernel.exit! -1
        end
      end
      file.close
      begin
        p,s = Process.waitpid2 @pid
        success = s.success?
      rescue Errno::ECHILD
        success = true
      end
    end
    sleep 0.5
    path = Open.read(res).strip if File.exists? res
  end
  path = "NO RESULT" if path.nil? or path.empty?

  if success
    Log.info "#{Log.color :green, "SUCCESS"} #{Log.color :magenta, workflow.to_s}##{Log.color :yellow, task} -- #{Log.color :cyan, name}"
    return [path, true]
  else
    Log.info "#{Log.color :red, "ERROR"} #{Log.color :magenta, workflow.to_s}##{Log.color :yellow, task} -- #{Log.color :cyan, name}"
    return [path, false]
  end
end

workflow = ARGV.shift
raise ParameterException if workflow.nil?

task = ARGV.shift
task = nil if task == '--'

name = ARGV.shift if task
name = nil if name == '--'

orig_name = name

$saved_args = ARGV.dup

workflow = Workflow.require_workflow workflow

tasks = task ? [task] : workflow.libdir.examples.glob('*').collect{|file| File.basename file }

task_result = {}
TSV.traverse tasks, :threads => 5 do |task|
  names = name ? [name] : workflow.libdir.examples[task].glob('*').collect{|file| File.basename file }
  TSV.traverse names, :threads => 5 do |name|
    success = run_task workflow, task, name
    task_result[[task, name]] = success
  end
end


task_result.each do |code,res|
  task, name = code
  path, success = res
  if success
    if orig_name
      puts Open.read(path)
    else
      STDERR.puts "#{Log.color :green, "SUCCESS"} #{Log.color :magenta, workflow.to_s}##{Log.color :yellow, task} -- #{Log.color :cyan, name}"
      puts path
    end
  else
    STDERR.puts "#{Log.color :red, "ERROR"} #{Log.color :magenta, workflow.to_s}##{Log.color :yellow, task} -- #{Log.color :cyan, name}"
    puts path
  end
end