# typed: strict
# ----------------------------------------------------------------------------
#
#  Welcome to Baml! To use this generated code, please run the following:
#
#  $ gem install baml
#
# ----------------------------------------------------------------------------

# This file was generated by BAML: please do not edit it. Instead, edit the
# BAML files and re-generate this code using: baml-cli generate
# baml-cli is available with the baml package.
# gem install baml
require "sorbet-runtime"
require "baml"

module BamlClient


  class TypeBuilder
        extend T::Sig

        sig { void }
        def initialize
            @registry = T.let(Baml::Ffi::TypeBuilder.new, Baml::Ffi::TypeBuilder)
            @classes = T.let(Set["Example", "Example2"], T::Set[String])
            @enums = T.let(Set[], T::Set[String])
        end

        sig { returns(Baml::Ffi::TypeBuilder) }
        def _registry
            @registry
        end

        sig { returns(Baml::Ffi::FieldType) }
        def string
            @registry.string
        end

        sig { returns(Baml::Ffi::FieldType) }
        def int
            @registry.int
        end

        sig { returns(Baml::Ffi::FieldType) }
        def float
            @registry.float
        end

        sig { returns(Baml::Ffi::FieldType) }
        def bool
            @registry.bool
        end

        sig { params(inner_type: Baml::Ffi::FieldType).returns(Baml::Ffi::FieldType) }
        def list(inner_type)
            @registry.list(inner_type)
        end

        sig { returns(Baml::Ffi::FieldType) }
        def null
            @registry.null
        end

        sig { params(key_type: Baml::Ffi::FieldType, value_type: Baml::Ffi::FieldType).returns(Baml::Ffi::FieldType) }
        def map(key_type, value_type)
            @registry.map(key_type, value_type)
        end

        sig { params(types: T::Array[Baml::Ffi::FieldType]).returns(Baml::Ffi::FieldType) }
        def union(types)
            @registry.union(types)
        end

        sig { params(name: String).returns(ClassBuilder) }
        def add_class(name)
            if @classes.include?(name)
                raise "Class with name #{name} already exists."
            end
            if @enums.include?(name)
                raise "Enum with name #{name} already exists."
            end
            @classes.add(name)
            ClassBuilder.new(@registry, name)
        end

        sig { params(name: String).returns(EnumBuilder) }
        def add_enum(name)
            if @classes.include?(name)
                raise "Class with name #{name} already exists."
            end
            if @enums.include?(name)
                raise "Enum with name #{name} already exists."
            end
            @enums.add(name)
            EnumBuilder.new(@registry, name)
        end

        sig { params(baml: String).void }
        def add_baml(baml)
            @registry.add_baml(baml, Baml::Internal::DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOU_RE_DOING_RUNTIME)
        end

        class ClassBuilder
            extend T::Sig

            sig { params(registry: Baml::Ffi::TypeBuilder, name: String, properties: T.nilable(T::Set[String])).void }
            def initialize(registry, name, properties = nil)
                @builder = T.let(registry.class_(name), Baml::Ffi::ClassBuilder)
                @properties = T.let(properties == nil ? Set.new : properties, T::Set[String])
            end

            sig { returns(Baml::Ffi::FieldType) }
            def type
                @builder.field
            end

            sig { params(name: String, type: Baml::Ffi::FieldType).returns(Baml::Ffi::FieldType) }
            def add_property(name, type)
                if @properties.include?(name)
                    raise "Property #{name} already exists."
                end
                @properties.add(name)
                @builder.property(name).type(type)
            end
        end

        class EnumBuilder
            extend T::Sig

            sig { params(registry: Baml::Ffi::TypeBuilder, name: String, values: T.nilable(T::Set[String])).void }
            def initialize(registry, name, values = nil)
                @builder = T.let(registry.enum(name), Baml::Ffi::EnumBuilder)
                @values = T.let(values == nil ? Set.new : values, T::Set[String])
            end

            sig { returns(Baml::Ffi::FieldType) }
            def type
                @builder.field
            end

            sig { params(name: String).returns(Baml::Ffi::FieldType) }
            def add_value(name)
                if @values.include?(name)
                    raise "Value #{name} already exists."
                end
                @values.add(name)
                @builder.value(name)
            end
        end




  end

end
