#!/usr/bin/env ruby -w

require 'fileutils'

def run(cmd)
  puts "Running command: #{cmd}"
  raise "ERROR: Command failed with exit code #{$?}" unless system cmd
end

root_dir = File.expand_path(ENV['MULTIRUBY'] ||
                            File.join(ENV['HOME'], ".multiruby"))

unless test ?d, root_dir then
  puts "creating #{root_dir}"
  Dir.mkdir root_dir, 0700
end

versions = []
Dir.chdir root_dir do
  %w(build install versions).each do |dir|
    unless test ?d, dir then
      puts "creating #{dir}"
      Dir.mkdir dir
      if dir == "versions" then
        puts "  Downloading initial ruby tarballs to ~/.multiruby/versions:"
        Dir.chdir dir do
          files = %w[ ruby-1.8.6-p111.tar.gz 1.9/ruby-1.9.0-0.tar.gz ]
          files.each do |file|
            require 'open-uri'
            open("http://ftp.ruby-lang.org/pub/ruby/#{file}") do |f|
              base = File.basename file
              puts "    #{base} via HTTP... this might take a while."
              File.open base, 'w' do |out|
                out.write f.read
              end
            end
          end
        end
        puts "  ...done"
        puts "  Put other ruby tarballs in ~/.multiruby/versions to use them."
      end
    end
  end

  tarballs = Dir["versions/rubygems*.tgz"]
  raise "You should delete all but one rubygem tarball" if tarballs.size > 1
  rubygem_tarball = File.expand_path tarballs.last rescue nil

  Dir.chdir "build" do
    Dir["../versions/ruby*.tar.gz"].each do |tarball|
      next if tarball =~ /rubygems/
      build_dir = File.basename tarball, ".tar.gz"
      version = build_dir.sub(/^ruby-?/, '')
      versions << version
      inst_dir = "#{root_dir}/install/#{version}"
      unless test ?d, inst_dir then
        unless test ?d, build_dir then
          puts "creating #{inst_dir}"
          Dir.mkdir inst_dir
          run "tar zxf #{tarball}"
        end
        Dir.chdir build_dir do
          puts "building and installing #{version}"
          run "autoconf" unless test ?f, "configure"
          FileUtils.rm_r "ext/readline" if test ?d, "ext/readline"
          run "./configure --prefix #{inst_dir} &> log.configure" unless test ?f, "Makefile"
          run "nice make -j4 &> log.build"
          run "make install &> log.install"
          build_dir = Dir.pwd

          if rubygem_tarball and version !~ /1[._-]9/ then
            rubygems = File.basename rubygem_tarball, ".tgz"
            run "tar zxf #{rubygem_tarball}" unless test ?d, rubygems

            Dir.chdir rubygems do
              run "../ruby ./setup.rb &> ../log.rubygems"
            end
          end
        end
      end
    end
  end

  # pick up rubinius - allows for simple symlinks to your build dir
  Dir.chdir('install') do
    versions.push(*Dir["rubinius*"])
  end
end

versions = ENV['VERSIONS'].split(/:/) if ENV.has_key? 'VERSIONS'

results = {}
versions.each do |version|
  ruby = "#{root_dir}/install/#{version}/bin/ruby"
  ruby.sub!(/bin.ruby/, 'shotgun/rubinius') if version =~ /rubinius/

  puts
  puts "VERSION = #{version}"
  cmd = [ruby, ARGV].flatten.map { |s| s =~ /\"/ ? "'#{s}'" : s }.join(' ')
  cmd.sub!(/#{ENV['HOME']}/, '~')
  puts "CMD     = #{cmd}"
  puts
  system ruby, *ARGV
  puts
  puts "RESULT = #{$?}"
  results[version] = $?
end

passed, failed = results.keys.partition { |v| results[v] == 0 }

puts
puts "TOTAL RESULT = #{failed.size} failures out of #{results.size}"
puts
puts "Passed: #{passed.join(", ")}"
puts "Failed: #{failed.join(", ")}"

exit failed.size
