# typed: strict

module Tapioca::Compilers
  class AttrJsonActivemodelDsl < Tapioca::Dsl::Compiler
    extend T::Sig

    ConstantType = type_member { { fixed: T.class_of(::AttrJson::Model) } }

    sig { override.returns(T::Enumerable[Module]) }
    def self.gather_constants
      all_classes.select { |c| c < ::AttrJson::Model }
    end

    sig { override.void }
    def decorate
      root.create_path(constant) do |klass|
        compiler =
          T.unsafe(Tapioca::Dsl::Compilers::ActiveModelAttributes).allocate
        registry = T.unsafe(constant).attr_json_registry
        T
          .cast(registry.attribute_names, T::Array[Symbol])
          .each do |name|
            attribute = T.cast(registry[name], AttrJson::AttributeDefinition)
            type = attribute.type
            type = T.unsafe(compiler).send(:type_for, type)
            T.unsafe(compiler).send(:generate_method, klass, name.to_s, type)
            T.unsafe(compiler).send(:generate_method, klass, "#{name}=", type)
          end
      end
    end
  end
end
