require 'mscorlib'
require 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL'
require 'Microsoft.Scripting, Version=1.0.0.5000, Culture=neutral, PublicKeyToken=null'
require 'Microsoft.Scripting.Core, Version=1.0.0.5000, Culture=neutral, PublicKeyToken=null'
require 'IronRuby, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
include System::Collections::Generic

def usage()

	puts <<EOF
irc: The Command Line Ruby Compiler
Usage: ir.exe irc.rb [options] file [file ...]

Options:
    /target:dll           Compile only into dll (default)
    /out:output_file      Output file name (default is <first_file>.<target>)
    /verbose              Verbose output
    /? /h                 This message
    
Example:
    ir.exe ir.exe /target:dll in.rb in2.rb
EOF

end

setup = Microsoft::Scripting::Hosting::ScriptRuntimeSetup.new
setup.language_setups.add(IronRuby::Ruby.create_language_setup())
runtime = Microsoft::Scripting::Hosting::ScriptRuntime.new(setup)
context = IronRuby::Ruby.get_execution_context(runtime)

files = []
target = "dll"
error = nil
showUsage = false
outfile = nil
useverbose = false

# parse the command line
i = 0
l = ARGV.length
(ARGV.length).times do |i|
	arg = ARGV[i]
	if arg.length > 0
		if arg[0..0] == "-" || arg[0..0] == "/"
			arg = arg.sub(/^-|\/+/, "")
			pieces = arg.split(':')
			if pieces[0] == "target"
				target = nil
				if pieces.length > 1
					target = pieces[1]
				end
				if target == nil || (target != nil && target != "dll" && target != "exe" && target != "winexe")
					error = "Error: Unknown target " + target
					break
				end
			elsif pieces[0] == "h" || pieces[0] == "help" || pieces[0] == "usage" || pieces[0] == "?"
				showUsage = true
				break
			elsif pieces[0] == "out"
				if pieces.length == 1
					error = "Error: Output file not specified"
					break
				end
				outfile = pieces[1]
			elsif pieces[0] == "verbose"
				useverbose = true
			else
				puts "Warning: Unknown argument " + pieces[0]
			end
		else
			files << arg
		end
	end
end

if error == nil && files.length == 0 && !showUsage
	error = "Error: No input files specified"
end

# check for errors, print & exit if so
if error != nil || showUsage
	if error != nil
		puts error
		puts "\n"
	end
	usage()
	exit 1
end

# have the list of files, do real work
if outfile == nil
	outfile = files[0]
	outfile = outfile.sub(/\.[^\.]+$/, "")
end

if outfile.index(".") == nil
	if target == "winexe"
		outfile += ".exe"
	else
		outfile += "." + target
	end
end

codes = List.of(Microsoft::Scripting::ScriptCode).new()

files.each do |file|
	file = context.Context.DomainManager.Platform.get_full_path(file)
	if useverbose
		puts "Compiling " + file + "..."
	end
	sourceUnit = context.Context.create_file_unit(file, System::Text::Encoding.Default, Microsoft::Scripting::SourceCodeKind.File)

	compilerOptions = context.Context.get_compiler_options()
	#compilerOptions.IsIncluded = true;
	#compilerOptions.IsWrapped = true; // (flags & LoadFlags.LoadIsolated) != 0;

	scriptCode = sourceUnit.compile(compilerOptions, context.RuntimeErrorSink)

	#scriptCode.ensure_compiled()

	codes.add(scriptCode)
end

# now actually create the output
outfile = context.Context.DomainManager.Platform.get_full_path(outfile)
if useverbose
	puts "Creating output file " + outfile + "..."
end

Microsoft::Scripting::ScriptCode.save_to_assembly(outfile, codes.to_array())

if useverbose
	puts "Done"
end
