class Tapioca::Gem::Listeners::YardDoc

def documentation_comments(name, sigs: [])

: (String name, ?sigs: Array[RBI::Sig]) -> Array[RBI::Comment]
def documentation_comments(name, sigs: [])
  yard_docs = YARD::Registry.at(name)
  return [] unless yard_docs
  docstring = yard_docs.docstring
  return [] if /(copyright|license)/i.match?(docstring)
  comments = docstring.lines
    .reject { |line| IGNORED_COMMENTS.any? { |comment| line.include?(comment) } || rbs_comment?(line) }
    .map! { |line| RBI::Comment.new(line) }
  tags = yard_docs.tags
  tags.reject! { |tag| IGNORED_SIG_TAGS.include?(tag.tag_name) } unless sigs.empty?
  comments << RBI::Comment.new("") if comments.any? && tags.any?
  tags.sort_by(&:tag_name).each do |tag|
    line = +"@#{tag.tag_name}"
    tag_name = tag.name
    line << " #{tag_name}" if tag_name
    tag_types = tag.types
    line << " [#{tag_types.join(", ")}]" if tag_types&.any?
    tag_text = tag.text
    if tag_text && !tag_text.empty?
      text_lines = tag_text.lines
      # Example are a special case because we want the text to start on the next line
      line << " #{text_lines.shift&.strip}" unless tag.tag_name == "example"
      text_lines.each do |text_line|
        line << "\n  #{text_line.strip}"
      end
    end
    comments << RBI::Comment.new(line)
  end
  comments
end

def ignore?(event)

: (NodeAdded event) -> bool
@override
def ignore?(event)
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
end

def initialize(pipeline)

: (Pipeline pipeline) -> void
def initialize(pipeline)
  YARD::Registry.clear
  super(pipeline)
  pipeline.gem.parse_yard_docs
end

def on_const(event)

: (ConstNodeAdded event) -> void
@override
def on_const(event)
  event.node.comments = documentation_comments(event.symbol)
end

def on_method(event)

: (MethodNodeAdded event) -> void
@override
def on_method(event)
  separator = event.constant.singleton_class? ? "." : "#"
  event.node.comments = documentation_comments(
    "#{event.symbol}#{separator}#{event.node.name}",
    sigs: event.node.sigs,
  )
end

def on_scope(event)

: (ScopeNodeAdded event) -> void
@override
def on_scope(event)
  event.node.comments = documentation_comments(event.symbol)
end

def rbs_comment?(line)

: (String line) -> bool
def rbs_comment?(line)
  line.strip.start_with?(": ", "| ")
end