#include "ruby/ruby.h"
#include "vm_core.h"

static const char prelude_name0[] = "<internal:prelude>";
static const char prelude_code0[] =
"\n"
"# Mutex\n"
"\n"
"class Mutex\n"
"  def synchronize\n"
"    self.lock\n"
"    begin\n"
"      yield\n"
"    ensure\n"
"      self.unlock rescue nil\n"
"    end\n"
"  end\n"
"end\n"
"\n"
"# Thread\n"
"\n"
"class Thread\n"
"  MUTEX_FOR_THREAD_EXCLUSIVE = Mutex.new\n"
"  def self.exclusive\n"
"    MUTEX_FOR_THREAD_EXCLUSIVE.synchronize{\n"
"      yield\n"
"    }\n"
"  end\n"
"end\n"
"\n"
"def require_relative(relative_feature)\n"
"  c = caller.first\n"
"  e = c.rindex(/:\\d+:in /)\n"
"  file = $`\n"
"  if /\\A\\((.*)\\)/ =~ file # eval, etc.\n"
"    raise LoadError, \"require_relative is called in #{$1}\"\n"
"  end\n"
"  absolute_feature = File.expand_path(File.join(File.dirname(file), relative_feature))\n"
"  require absolute_feature\n"
"end\n"
;
static const char prelude_name1[] = "<internal:prelude>";
static const char prelude_code1[] =
"%w'enc/encdb enc/trans/transdb'.each do |init|\n"
"  begin\n"
"    require(init)\n"
"  rescue LoadError\n"
"  end\n"
"end\n"
;
static const char prelude_name2[] = "<internal:gem_prelude>";
static const char prelude_code2[] =
"TMP_RUBY_PREFIX = $:.reverse.find{|e|e!=\".\"}.sub(%r{(.*)/lib/.*}m, \"\\\\1\")\n"
"# depends on: array.rb dir.rb env.rb file.rb hash.rb module.rb regexp.rb\n"
"# vim: filetype=ruby\n"
"# THIS FILE WAS AUTOGENERATED, DO NOT EDIT\n"
"\n"
"# NOTICE: Ruby is during initialization here. \n"
"#   * Encoding.default_external does not reflects -E.\n"
"#   * Should not expect Encoding.default_internal.\n"
"#   * Locale encoding is available.\n"
"if defined?(Gem) then\n"
"\n"
"  module Kernel\n"
"\n"
"    def gem(gem_name, *version_requirements)\n"
"      Gem.push_gem_version_on_load_path(gem_name, *version_requirements)\n"
"    end\n"
"\n"
"  end\n"
"\n"
"  module Gem\n"
"\n"
"    class LoadError < ::LoadError\n"
"    end\n"
"\n"
"    ConfigMap = {\n"
"      :sitedir => \"#{TMP_RUBY_PREFIX}/lib/ruby/site_ruby\",\n"
"      :ruby_version => \"1.9.1\",\n"
"      :libdir => \"#{TMP_RUBY_PREFIX}/lib\",\n"
"      :sitelibdir => \"#{TMP_RUBY_PREFIX}/lib/ruby/site_ruby/1.9.1\",\n"
"      :arch => \"arm-linux\",\n"
"      :bindir => \"#{TMP_RUBY_PREFIX}/bin\",\n"
"      :EXEEXT => \"\",\n"
"      :RUBY_SO_NAME => \"ruby\",\n"
"      :ruby_install_name => \"ruby\"\n"
"    }\n"
"\n"
"    def self.dir\n"
"      @gem_home ||= nil\n"
"      set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home\n"
"      @gem_home\n"
"    end\n"
"\n"
"    def self.path\n"
"      @gem_path ||= nil\n"
"      unless @gem_path\n"
"        paths = [ENV['GEM_PATH']]\n"
"        paths << APPLE_GEM_HOME if defined? APPLE_GEM_HOME\n"
"        set_paths(paths.compact.join(File::PATH_SEPARATOR))\n"
"      end\n"
"      @gem_path\n"
"    end\n"
"\n"
"    def self.post_install(&hook)\n"
"      @post_install_hooks << hook\n"
"    end\n"
"\n"
"    def self.post_uninstall(&hook)\n"
"      @post_uninstall_hooks << hook\n"
"    end\n"
"\n"
"    def self.pre_install(&hook)\n"
"      @pre_install_hooks << hook\n"
"    end\n"
"\n"
"    def self.pre_uninstall(&hook)\n"
"      @pre_uninstall_hooks << hook\n"
"    end\n"
"\n"
"    def self.set_home(home)\n"
"      @gem_home = home\n"
"      ensure_gem_subdirectories(@gem_home)\n"
"    end\n"
"\n"
"    def self.set_paths(gpaths)\n"
"      if gpaths\n"
"        @gem_path = gpaths.split(File::PATH_SEPARATOR)\n"
"        @gem_path << Gem.dir\n"
"      else\n"
"        @gem_path = [Gem.dir]\n"
"      end\n"
"      @gem_path.uniq!\n"
"      @gem_path.each do |gp| ensure_gem_subdirectories(gp) end\n"
"    end\n"
"\n"
"    def self.ensure_gem_subdirectories(path)\n"
"    end\n"
"\n"
"  \n"
"    @post_install_hooks   ||= []\n"
"    @post_uninstall_hooks ||= []\n"
"    @pre_uninstall_hooks  ||= []\n"
"    @pre_install_hooks    ||= []\n"
"  \n"
"    ##\n"
"    # An Array of the default sources that come with RubyGems\n"
"  \n"
"    def self.default_sources\n"
"      %w[http://gems.rubyforge.org/]\n"
"    end\n"
"  \n"
"    ##\n"
"    # Default home directory path to be used if an alternate value is not\n"
"    # specified in the environment\n"
"  \n"
"    def self.default_dir\n"
"      if defined? RUBY_FRAMEWORK_VERSION then\n"
"        File.join File.dirname(ConfigMap[:sitedir]), 'Gems',\n"
"                  ConfigMap[:ruby_version]\n"
"      elsif RUBY_VERSION > '1.9' then\n"
"        File.join(ConfigMap[:libdir], ConfigMap[:ruby_install_name], 'gems',\n"
"                  ConfigMap[:ruby_version])\n"
"      else\n"
"        File.join(ConfigMap[:libdir], ruby_engine, 'gems',\n"
"                  ConfigMap[:ruby_version])\n"
"      end\n"
"    end\n"
"  \n"
"    ##\n"
"    # Path for gems in the user's home directory\n"
"  \n"
"    def self.user_dir\n"
"      File.join(Gem.user_home, '.gem', ruby_engine,\n"
"                ConfigMap[:ruby_version])\n"
"    end\n"
"  \n"
"    ##\n"
"    # Default gem load path\n"
"  \n"
"    def self.default_path\n"
"      [user_dir, default_dir]\n"
"    end\n"
"  \n"
"    ##\n"
"    # Deduce Ruby's --program-prefix and --program-suffix from its install name\n"
"  \n"
"    def self.default_exec_format\n"
"      baseruby = ConfigMap[:BASERUBY] || 'ruby'\n"
"      ConfigMap[:RUBY_INSTALL_NAME].sub(baseruby, '%s') rescue '%s'\n"
"    end\n"
"  \n"
"    ##\n"
"    # The default directory for binaries\n"
"  \n"
"    def self.default_bindir\n"
"      if defined? RUBY_FRAMEWORK_VERSION then # mac framework support\n"
"        '/usr/bin'\n"
"      else # generic install\n"
"        ConfigMap[:bindir]\n"
"      end\n"
"    end\n"
"  \n"
"    ##\n"
"    # The default system-wide source info cache directory\n"
"  \n"
"    def self.default_system_source_cache_dir\n"
"      File.join Gem.dir, 'source_cache'\n"
"    end\n"
"  \n"
"    ##\n"
"    # The default user-specific source info cache directory\n"
"  \n"
"    def self.default_user_source_cache_dir\n"
"      File.join Gem.user_home, '.gem', 'source_cache'\n"
"    end\n"
"  \n"
"    ##\n"
"    # A wrapper around RUBY_ENGINE const that may not be defined\n"
"  \n"
"    def self.ruby_engine\n"
"      if defined? RUBY_ENGINE then\n"
"        RUBY_ENGINE\n"
"      else\n"
"        'ruby'\n"
"      end\n"
"    end\n"
"  \n"
"  \n"
"\n"
"    # Methods before this line will be removed when QuickLoader is replaced\n"
"    # with the real RubyGems\n"
"\n"
"    GEM_PRELUDE_METHODS = Gem.methods(false)\n"
"\n"
"    begin\n"
"      verbose, debug = $VERBOSE, $DEBUG\n"
"      $DEBUG = $VERBOSE = nil\n"
"\n"
"      begin\n"
"        require 'rubygems/defaults/operating_system'\n"
"      rescue ::LoadError\n"
"      end\n"
"\n"
"      if defined?(RUBY_ENGINE) then\n"
"        begin\n"
"          require \"rubygems/defaults/#{RUBY_ENGINE}\"\n"
"        rescue ::LoadError\n"
"        end\n"
"      end\n"
"    ensure\n"
"      $VERBOSE, $DEBUG = verbose, debug\n"
"    end\n"
"\n"
"    module QuickLoader\n"
"\n"
"      @loaded_full_rubygems_library = false\n"
"\n"
"      def self.load_full_rubygems_library\n"
"        return if @loaded_full_rubygems_library\n"
"\n"
"        @loaded_full_rubygems_library = true\n"
"\n"
"        class << Gem\n"
"          Gem::GEM_PRELUDE_METHODS.each do |method_name|\n"
"            undef_method method_name\n"
"          end\n"
"        end\n"
"\n"
"        Kernel.module_eval do\n"
"          undef_method :gem if method_defined? :gem\n"
"        end\n"
"\n"
"        $\".delete File.join(Gem::ConfigMap[:libdir],\n"
"                            Gem::ConfigMap[:ruby_install_name],\n"
"                            Gem::ConfigMap[:ruby_version], 'rubygems.rb')\n"
"\n"
"        require 'rubygems'\n"
"      end\n"
"\n"
"      GemPaths = {}\n"
"      GemVersions = {}\n"
"\n"
"      def push_gem_version_on_load_path(gem_name, *version_requirements)\n"
"        if version_requirements.empty?\n"
"          unless GemPaths.has_key?(gem_name)\n"
"            raise Gem::LoadError.new(\"Could not find RubyGem #{gem_name} (>= 0)\\n\")\n"
"          end\n"
"\n"
"          # highest version gems already active\n"
"          return false\n"
"        else\n"
"          if version_requirements.length > 1\n"
"            QuickLoader.load_full_rubygems_library\n"
"            return gem(gem_name, *version_requirements)\n"
"          end\n"
"\n"
"          requirement, version = version_requirements[0].split\n"
"          requirement.strip!\n"
"\n"
"          if requirement == \">\" || requirement == \">=\"\n"
"            if (GemVersions[gem_name] <=> Gem.calculate_integers_for_gem_version(version)) >= 0\n"
"              return false\n"
"            end\n"
"          elsif requirement == \"~>\"\n"
"            loaded_version = GemVersions[gem_name]\n"
"            required_version = Gem.calculate_integers_for_gem_version(version)\n"
"            if loaded_version && (loaded_version[0] == required_version[0])\n"
"              return false\n"
"            end\n"
"          end\n"
"\n"
"          QuickLoader.load_full_rubygems_library\n"
"          gem(gem_name, *version_requirements)\n"
"        end\n"
"      end\n"
"\n"
"      def calculate_integers_for_gem_version(gem_version)\n"
"        numbers = gem_version.split(\".\").collect {|n| n.to_i}\n"
"        numbers.pop while numbers.last == 0\n"
"        numbers << 0 if numbers.empty?\n"
"        numbers\n"
"      end\n"
"\n"
"      def push_all_highest_version_gems_on_load_path\n"
"        Gem.path.each do |path|\n"
"          gems_directory = File.join(path, \"gems\")\n"
"          if File.exist?(gems_directory)\n"
"            Dir.entries(gems_directory).each do |gem_directory_name|\n"
"              next if gem_directory_name == \".\" || gem_directory_name == \"..\"\n"
"              dash = gem_directory_name.rindex(\"-\")\n"
"              next if dash.nil?\n"
"              gem_name = gem_directory_name[0...dash]\n"
"              current_version = GemVersions[gem_name]\n"
"              new_version = calculate_integers_for_gem_version(gem_directory_name[dash+1..-1])\n"
"              if current_version\n"
"                if (current_version <=> new_version) == -1\n"
"                  GemVersions[gem_name] = new_version\n"
"                  GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)\n"
"                end\n"
"              else\n"
"                GemVersions[gem_name] = new_version\n"
"                GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)\n"
"              end\n"
"            end\n"
"          end\n"
"        end\n"
"\n"
"        require_paths = []\n"
"\n"
"        GemPaths.each_value do |path|\n"
"          if File.exist?(file = File.join(path, \".require_paths\")) then\n"
"            paths = File.read(file).split.map do |require_path|\n"
"              File.join path, require_path\n"
"            end\n"
"\n"
"            require_paths.concat paths\n"
"          else\n"
"            require_paths << file if File.exist?(file = File.join(path, \"bin\"))\n"
"            require_paths << file if File.exist?(file = File.join(path, \"lib\"))\n"
"          end\n"
"        end\n"
"\n"
"        # \"tag\" the first require_path inserted into the $LOAD_PATH to enable\n"
"        # indexing correctly with rubygems proper when it inserts an explicitly\n"
"        # gem version\n"
"        unless require_paths.empty?\n"
"          require_paths.first.instance_variable_set(:@gem_prelude_index, true)\n"
"        end\n"
"        # gem directories must come after -I and ENV['RUBYLIB']\n"
"        $:[$:.index(ConfigMap[:sitelibdir]),0] = require_paths\n"
"      end\n"
"\n"
"      def const_missing(constant)\n"
"        QuickLoader.load_full_rubygems_library\n"
"        if Gem.const_defined?(constant)\n"
"          Gem.const_get(constant)\n"
"        else\n"
"          super\n"
"        end\n"
"      end\n"
"\n"
"      def method_missing(method, *args, &block)\n"
"        QuickLoader.load_full_rubygems_library\n"
"        super unless Gem.respond_to?(method)\n"
"        Gem.send(method, *args, &block)\n"
"      end\n"
"    end\n"
"\n"
"    extend QuickLoader\n"
"\n"
"  end\n"
"\n"
"  begin\n"
"    Gem.push_all_highest_version_gems_on_load_path\n"
"    $\" << File.join(Gem::ConfigMap[:libdir], Gem::ConfigMap[:ruby_install_name],\n"
"                    Gem::ConfigMap[:ruby_version], \"rubygems.rb\")\n"
"  rescue Exception => e\n"
"    puts \"Error loading gem paths on load path in gem_prelude\"\n"
"    puts e\n"
"    puts e.backtrace.join(\"\\n\")\n"
"  end\n"
"\n"
"end\n"
"\n"
"Object.class_eval { remove_const \"TMP_RUBY_PREFIX\" }"
;

void
Init_prelude(void)
{
  rb_iseq_eval(rb_iseq_compile(
    rb_str_new(prelude_code0, sizeof(prelude_code0) - 1),
    rb_str_new(prelude_name0, sizeof(prelude_name0) - 1),
    INT2FIX(1)));

  rb_iseq_eval(rb_iseq_compile(
    rb_str_new(prelude_code1, sizeof(prelude_code1) - 1),
    rb_str_new(prelude_name1, sizeof(prelude_name1) - 1),
    INT2FIX(1)));

  rb_iseq_eval(rb_iseq_compile(
    rb_str_new(prelude_code2, sizeof(prelude_code2) - 1),
    rb_str_new(prelude_name2, sizeof(prelude_name2) - 1),
    INT2FIX(0)));

#if 0
    puts(prelude_code0);
    puts(prelude_code1);
    puts(prelude_code2);
#endif
}
