class WolfCore::InstanceApplicationSerializer

def self._attributes

def self._attributes
  @_attributes ||= []
end

def self._relationships

def self._relationships
  @_relationships ||= {}
end

def self.attributes(*attrs)

def self.attributes(*attrs)
  _attributes.concat(attrs.map(&:to_sym)).uniq!
end

def self.has_many(relationship, serializer:) # rubocop:disable Naming/PredicateName

rubocop:disable Naming/PredicateName
def self.has_many(relationship, serializer:) # rubocop:disable Naming/PredicateName
  _relationships[relationship.to_sym] = serializer
end

def self.has_one(relationship, serializer:) # rubocop:disable Naming/PredicateName

rubocop:disable Naming/PredicateName
def self.has_one(relationship, serializer:) # rubocop:disable Naming/PredicateName
  _relationships[relationship.to_sym] = serializer
end

def as_json

def as_json
  attributes = serialized_attributes
  relationships = serialized_relationships
  attributes.merge(relationships)
end

def initialize(object: nil, collection: nil, options: nil)

def initialize(object: nil, collection: nil, options: nil)
  @object = object
  @collection = collection
  @options = options || {}
end

def serialize(object: nil, options: nil)

def serialize(object: nil, options: nil)
  Result.try do
    @object = object if object
    options ||= {}
    @options = @options.merge(options)
    serialized_object = as_json(object: @object).with_indifferent_access
    Result.success(data: { serialized_object: serialized_object })
  end
end

def serialize_all(collection: nil, options: nil)

def serialize_all(collection: nil, options: nil)
  Result.try do
    @collection = collection if collection
    options ||= {}
    @options = @options.merge(options)
    results = @collection.map do |item|
      result = serialize(object: item, options: @options)
      result.raise_error
      result
    end
    Result.success(data: { serialized_collection: results.map { |result| result.data.serialized_object } })
  end
end

def serialized_attributes

def serialized_attributes
  self.class._attributes.each_with_object({}) do |attribute, hash|
    hash[attribute] = if respond_to?(attribute, true)
                        send(attribute)
                      elsif @object.respond_to?(attribute)
                        @object.public_send(attribute)
                      end
  end
end

def serialized_relationships

def serialized_relationships
  self.class._relationships.each_with_object({}) do |(key, serializer_class), hash|
    serializer = serializer_class.new(options: @options)
    related_object = @object.public_send(key)
    hash[key] = if related_object.is_a?(Enumerable)
                  serializer.serialize_all(collection: related_object)
                else
                  serializer.serialize(object: related_object)
                end
  end
end