class Lutaml::Model::Xml::Builder::Oga

def self.build(options = {}, &block)

def self.build(options = {}, &block)
  new(options, &block)
end

def <<(text)

def <<(text)
  @current_node.text(text)
end

def add_attribute(element, name, value)

def add_attribute(element, name, value)
  attribute = ::Oga::XML::Attribute.new(
    name: name,
    value: value.to_s,
  )
  if element.is_a?(Xml::Oga::Document)
    element.children.last.attributes << attribute
  else
    element.attributes << attribute
  end
end

def add_cdata(element, value)

def add_cdata(element, value)
  oga_cdata = ::Oga::XML::CData.new(text: value.to_s)
  if element.is_a?(Xml::Oga::Document)
    element.children.last.children << oga_cdata
  else
    element.children << oga_cdata
  end
end

def add_element(oga_element, child)

def add_element(oga_element, child)
  if child.is_a?(String)
    current_element = oga_element.is_a?(Xml::Oga::Document) ? current_node : oga_element
    add_xml_fragment(current_element, child)
  elsif oga_element.is_a?(Xml::Oga::Document)
    oga_element.children.last.children << child
  else
    oga_element.children << child
  end
end

def add_namespace_prefix(prefix)

def add_namespace_prefix(prefix)
  @current_namespace = prefix
  self
end

def add_text(element, text, cdata: false)

def add_text(element, text, cdata: false)
  text = text&.encode(encoding) if encoding && text.is_a?(String)
  return add_cdata(element, text) if cdata
  oga_text = ::Oga::XML::Text.new(text: text.to_s)
  append_text_node(element, oga_text)
end

def add_xml_fragment(element, content)

def add_xml_fragment(element, content)
  fragment = "<fragment>#{content}</fragment>"
  parsed_fragment = ::Oga.parse_xml(fragment)
  parsed_children = parsed_fragment.children.first.children
  if element.is_a?(Xml::Oga::Document)
    element.children.last.children += parsed_children
  else
    element.children += parsed_children
  end
end

def append_text_node(element, oga_text)

def append_text_node(element, oga_text)
  if element.is_a?(Xml::Oga::Document)
    children = element.children
    children.empty? ? children << oga_text : children.last.children << oga_text
  else
    element.children << oga_text
  end
end

def create_and_add_element(

def create_and_add_element(
  element_name,
  prefix: (prefix_unset = true
           nil),
  attributes: {},
  &block
)
  @current_namespace = nil if prefix.nil? && !prefix_unset
  prefixed_name = if prefix
                    "#{prefix}:#{element_name}"
                  elsif @current_namespace && !element_name.start_with?("#{@current_namespace}:")
                    "#{@current_namespace}:#{element_name}"
                  else
                    element_name
                  end
  if block
    element(prefixed_name, attributes, &block)
  else
    element(prefixed_name, attributes)
  end
end

def create_element(name, attributes = {}, &block)

def create_element(name, attributes = {}, &block)
  if @current_namespace && !name.start_with?("#{@current_namespace}:")
    name = "#{@current_namespace}:#{name}"
  end
  if block
    element(name, attributes, &block)
  else
    element(name, attributes)
  end
end

def element(name, attributes = {})

def element(name, attributes = {})
  oga_element = ::Oga::XML::Element.new(name: name)
  if block_given?
    element_attributes(oga_element, attributes)
    @current_node.children << oga_element
    # Save previous node to reset the pointer for the rest of the iteration
    previous_node = @current_node
    # Set current node to new element as pointer for the block
    @current_node = oga_element
    yield(self)
    # Reset the pointer for the rest of the iterations
    @current_node = previous_node
  end
  oga_element
end

def element_attributes(oga_element, attributes)

def element_attributes(oga_element, attributes)
  oga_element.attributes = attributes.map do |name, value|
    value = value.uri unless value.is_a?(String)
    ::Oga::XML::Attribute.new(
      name: name,
      value: value,
      element: oga_element,
    )
  end
end

def initialize(options = {})

def initialize(options = {})
  @document = Xml::Oga::Document.new
  @current_node = @document
  @encoding = options[:encoding]
  yield(self) if block_given?
end

def method_missing(method_name, *args)

def method_missing(method_name, *args)
  if block_given?
    @current_node.public_send(method_name, *args) do
      yield(self)
    end
  else
    @current_node.public_send(method_name, *args)
  end
end

def parent

def parent
  @document
end

def respond_to_missing?(method_name, include_private = false)

def respond_to_missing?(method_name, include_private = false)
  @current_node.respond_to?(method_name) || super
end

def text(value = nil)

def text(value = nil)
  return @current_node.inner_text if value.nil?
  str = value.is_a?(Array) ? value.join : value
  @current_node.children << ::Oga::XML::Text.new(text: str)
end