module ReeMapper

def self.build_mapper_factory(mod)

def self.build_mapper_factory(mod)
  pckg_name = ReeString::Underscore.new.call(mod.name)
  factory_path = "#{pckg_name}/mapper_factory"
  if Ree.irb_mode? && Object.const_defined?("#{mod.name}::MapperFactory") && mod != self
    return Object.const_get("#{mod.name}::MapperFactory").new
  end
  mapper_factory_klass = if package_file_exists?(factory_path) && mod != self
    package_require(factory_path)
    Object.const_get("#{mod.name}::MapperFactory")
  else
    ReeMapper::DefaultFactory
  end
  mapper_factory_klass.new
end

def self.get_mapper_factory(mod)

def self.get_mapper_factory(mod)
  if !mod.is_a?(Module)
    raise Ree::Error.new("module should be provided", :invalid_dsl_usage)
  end
  if mod.name.nil?
    raise Ree::Error.new("anonymous modules are not supported", :invalid_dsl_usage)
  end
  if mod.name.split('::').size > 1
    raise Ree::Error.new("top level module should be provided", :invalid_dsl_usage)
  end
  factory = mod.instance_variable_get(:@mapper_factory)
  return factory if factory
  if !mod.instance_variable_get(:@mapper_semaphore)
    mod.instance_variable_set(:@mapper_semaphore, Mutex.new)
  end
  mod.instance_variable_get(:@mapper_semaphore).synchronize do
    factory = self.build_mapper_factory(mod)
    mod.instance_variable_set(:@mapper_factory, factory)
  end
  factory
end