module Inline
  require 'java'

  class Java
    $CLASSPATH << Inline.directory

    JFile = java.io.File
    import javax.tools.ToolProvider
    import javax.tools.SimpleJavaFileObject
    import javax.tools.StandardLocation

    def initialize(mod)
      @context = mod
      @src = ""
      @imports = []
      @sigs = []
    end

    def import(cls)
      @imports << cls
    end

    def load_cache
      false
    end

    def java(src)
      @src << src << "\n"
      signature = @src.match(/public static\W+(\w+)\W+([a-zA-Z0-9_]+)\((.*)\)/)
      raise "Could not parse method signature" unless signature
      @sigs << [signature[1], signature[2], signature[3]]
    end

    def build
      compiler = ToolProvider.system_java_compiler
      file_mgr = compiler.get_standard_file_manager(nil, nil, nil)
      file_mgr.set_location(StandardLocation::CLASS_OUTPUT, [JFile.new(Inline.directory)])

      @name = "Java#{@src.hash.abs}"

      imports = "import " + @imports.join(";\nimport ") + ";" if @imports.size > 0
      full_src = "
        #{imports}
        public class #{@name} {
        #{@src}
        }
      "

      filename = "#{Inline.directory}/#{@name}.java"
      File.open(filename, "w") {|file| file.write(full_src)}
      file_objs = file_mgr.get_java_file_objects_from_strings([filename])

      compiler.get_task(nil, file_mgr, nil, nil, nil, file_objs).call
      file_mgr.close
    end

    def load
      @sigs.each do |sig|
        @context.module_eval "const_set :#{@name}, ::Java.const_get(:#{@name}); def #{sig[1]}(*args); #{@name}.#{sig[1]}(*args); end"
      end
    end
  end
end