module ReeEnum::DSL::ClassMethods

def enum(name, &proc)

def enum(name, &proc)
  dsl = Ree::ObjectDsl.new(
    Ree.container.packages_facade, name, self, :object
  )
  dsl.instance_exec(&proc) if block_given?
  dsl.tags(["object", "enum"])
  klass = dsl.object.klass
  klass.send(:include, ReeEnum::Enumerable)
  klass.setup_enum(dsl.object.name)
  Ree.container.compile(dsl.package, name)
end

def register_as_mapper_type

def register_as_mapper_type
  register_as_swagger_type
  mapper_factory = ReeMapper.get_mapper_factory(
    Object.const_get(self.name.split('::').first)
  )
  mapper_factory.register_type(
    self.get_enum_name, type_for_mapper
  )
end

def register_as_swagger_type

def register_as_swagger_type
  swagger_type_registrator = ReeSwagger::RegisterType.new
  [:casters, :serializers].each do |kind|
    swagger_type_registrator.call(
      kind,
      type_for_mapper.class,
      ->(type, _build_schema) {
        type.enum.swagger_definition
      }
    )
  end
end

def swagger_definition

def swagger_definition
  return @swagger_definition if defined? @swagger_definition
  value_type = get_values.value_type
  type = if value_type == String
    "string"
  elsif value_type == Integer
    "integer"
  else
    raise NotImplementedError, "value_type #{value_type} is not supported"
  end
  @swagger_definition = {
    type: type,
    enum: get_values.each.map(&:value)
  }
end

def type_for_mapper

def type_for_mapper
  return @type_for_mapper if defined? @type_for_mapper
  value_type = get_values.value_type
  klass = if value_type == String
    StringValueEnumMapper
  elsif value_type == Integer
    IntegerValueEnumMapper
  else
    raise NotImplementedError, "value_type #{value_type} is not supported"
  end
  @type_for_mapper = klass.new(self)
end