require 'virtualbox/ext/logger'

module VirtualBox
  module COM
    module Implementer
      class Base < AbstractImplementer
        include Logger

        # Returns the Ruby version as a float
        #
        # @return [Float]
        def ruby_version
          RUBY_VERSION.to_f
        end

        # Finds and returns the `COM::Interface` class associated with the type.
        # If the class does not exist, a `NameError` will be raised.
        #
        # @return [Class]
        def interface_klass(type)
          ::VirtualBox::COM::FFI::Util.interface_klass(type)
        end

        # Gives the C type and inferred type of a parameter type. Quite confusing
        # since the terminology is not consistent, but hopefully these examples
        # will help:
        #
        #   type => [pointer_type, internal_type]
        #   :int => [:int, :int]
        #   :MyStruct => [:pointer, :struct]
        #   :unicode_string => [:pointer, :unicode_string]
        #
        def infer_type(type)
          c_type = type

          begin
            if type == WSTRING
              # Handle strings as pointer types
              c_type = :pointer
            else
              # Try to get the class from the interfaces
              interface = interface_klass(type)

              c_type = :pointer

              # Depending on the class type, we're either dealing with an interface
              # or an enum
              if interface.superclass == COM::AbstractInterface
                type = :interface
                c_type = :pointer
              elsif interface.superclass == COM::AbstractEnum
                type = :enum
                c_type = :uint32
              end
            end
          rescue NameError,LoadError
            # Do nothing
          end

          [c_type, type]
        end

      end
    end
  end
end
