#!/usr/bin/env ruby
# frozen_string_literal: true

require 'optparse'

options = {
  parallel: [],
  then: []
}

OptionParser.new do |opts|
  opts.on("--parallel=LIST", Array) { |list| options[:parallel] = list }
  opts.on("--then=LIST", Array) { |list| options[:then] = list }
end.parse!

if options[:parallel].empty? && options[:then].empty?
  puts "Usage: #{$PROGRAM_NAME} [--parallel=task1,task2] [--then=task3,task4]"
  exit 1
end

ENV["SILENT_TESTS"] = "1"

def resolve_cmd(name)
  paths = [
    "./bin/linters/#{name}",
    "./bin/linters/helpers/#{name}"
  ]
  # Find an executable path, or default to executing the name directly
  paths.find { |p| File.executable?(p) } || name
end

def run_task(name)
  cmd = resolve_cmd(name)
  start_time = Time.now
  
  output = `DISABLE_SPRING=1 #{cmd} 2>&1`
  ext_code = $?.exitstatus
  elapsed = (Time.now - start_time).round
  success = (ext_code == 0)

  # Check if the script wraps its own output
  if output.include?("✅ SUCCESS") || output.include?("❌ FAILED")
    puts output
  else
    if success
      puts "✅ SUCCESS: #{cmd} (#{elapsed}s)"
    else
      puts "========================================"
      puts "❌ FAILED: #{cmd} (#{elapsed}s)"
      puts output
      puts ""
    end
  end
  success
end

threads = []
results = {}
mutex = Mutex.new

options[:parallel].each do |task_name|
  threads << Thread.new do
    success = run_task(task_name)
    mutex.synchronize { results[task_name] = success }
  end
end

unless options[:then].empty?
  threads << Thread.new do
    options[:then].each do |task_name|
      success = run_task(task_name)
      mutex.synchronize { results[task_name] = success }
      break unless success # Stop the sequential chain on failure!
    end
  end
end

threads.each(&:join)

if results.values.any? { |r| !r }
  exit 1
else
  exit 0
end
