module Platform
end

class Platform::OS

def self.calculate_current
# STUB this would use real data to figure out which class to use
OpenBSD
end

def self.resolve
missing = []

klass = calculate_current()
inst = klass.new

klass.ancestors.each do |anc|
break if anc == Platform::OS
anc.verify! inst, missing
end

unless missing.empty?
puts "Some platform functions were not found:"
missing.each do |meth|
puts " #{meth}"
end

unless ENV['PLATFORM_SOFT']
exit 1
end
end
end

def self.attach(name, *args)
@methods ||= []
@methods << name
begin
attach_function name, *args
rescue
end
end

def self.verify!(obj, missing)
if @methods
@methods.each do |meth|
unless obj.respond_to?(meth)
missing << meth
end
end
end
end
end

class POSIX < Platform::OS
end

class ModernUnix < POSIX
attach :lchmod, [:string, :mode_t], :int
attach :blah, [], :int
end

class BSD < ModernUnix
end

class OpenBSD < BSD
def lchmod
raise NotImplementedError, "OpenBSD does not have lchmod"
end
end


Platform::OS.resolve