class Dependabot::PullRequestCreator::MessageBuilder::LinkAndMentionSanitizer

def build_mention_link_text_nodes(text)

def build_mention_link_text_nodes(text)
  code_node = CommonMarker::Node.new(:code)
  code_node.string_content = insert_zero_width_space_in_mention(text)
  [code_node]
end

def build_mention_nodes(text)

def build_mention_nodes(text)
  nodes = T.let([], T::Array[CommonMarker::Node])
  scan = StringScanner.new(text)
  until scan.eos?
    line = scan.scan_until(MENTION_REGEX) ||
           scan.scan_until(EOS_REGEX)
    line_match = T.must(line).match(MENTION_REGEX)
    mention = line_match&.to_s
    text_node = CommonMarker::Node.new(:text)
    if mention && !mention.end_with?("/")
      text_node.string_content = line_match.pre_match
      nodes << text_node
      nodes << create_link_node(
        "https://github.com/#{mention.tr('@', '')}", mention.to_s
      )
    else
      text_node.string_content = line
      nodes << text_node
    end
  end
  nodes
end

def build_nwo_text_node(text)

def build_nwo_text_node(text)
  code_node = CommonMarker::Node.new(:code)
  code_node.string_content = text
  code_node
end

def build_team_mention_nodes(text)

def build_team_mention_nodes(text)
  nodes = T.let([], T::Array[CommonMarker::Node])
  scan = StringScanner.new(text)
  until scan.eos?
    line = scan.scan_until(TEAM_MENTION_REGEX) ||
           scan.scan_until(EOS_REGEX)
    line_match = T.must(line).match(TEAM_MENTION_REGEX)
    mention = line_match&.to_s
    text_node = CommonMarker::Node.new(:text)
    if mention
      text_node.string_content = line_match.pre_match
      nodes << text_node
      nodes += build_mention_link_text_nodes(mention.to_s)
    else
      text_node.string_content = line
      nodes << text_node
    end
  end
  nodes
end

def create_link_node(url, text)

def create_link_node(url, text)
  link_node = CommonMarker::Node.new(:link)
  code_node = CommonMarker::Node.new(:code)
  link_node.url = url
  code_node.string_content = insert_zero_width_space_in_mention(text)
  link_node.append_child(code_node)
  link_node
end

def initialize(github_redirection_service:)

def initialize(github_redirection_service:)
  @github_redirection_service = github_redirection_service
end

def insert_zero_width_space_in_mention(mention)

def insert_zero_width_space_in_mention(mention)
  mention.sub("@", "@\u200B").encode("utf-8")
end

def parent_node_link?(node)

def parent_node_link?(node)
  node.type == :link || (!node.parent.nil? && parent_node_link?(T.must(node.parent)))
end

def replace_github_host(text)

def replace_github_host(text)
  return text if !github_redirection_service.nil? && text.include?(T.must(github_redirection_service))
  text.gsub(
    /(www\.)?github.com/, github_redirection_service || "github.com"
  )
end

def replace_nwo_node(node)

def replace_nwo_node(node)
  match = T.must(node.string_content.match(GITHUB_NWO_REGEX))
  repo = match.named_captures.fetch("repo")
  number = match.named_captures.fetch("number")
  new_node = build_nwo_text_node("#{repo}##{number}")
  node.insert_before(new_node)
  node.delete
end

def sanitize_links(doc)

def sanitize_links(doc)
  doc.walk do |node|
    if node.type == :link && node.url.match?(GITHUB_REF_REGEX)
      node.each do |subnode|
        unless subnode.type == :text &&
               subnode.string_content.match?(GITHUB_REF_REGEX)
          next
        end
        last_match = T.must(subnode.string_content.match(GITHUB_REF_REGEX))
        number = last_match.named_captures.fetch("number")
        repo = last_match.named_captures.fetch("repo")
        subnode.string_content = "#{repo}##{number}"
      end
      node.url = replace_github_host(node.url)
    elsif node.type == :text &&
          node.string_content.match?(GITHUB_REF_REGEX)
      node.string_content = replace_github_host(node.string_content)
    end
  end
end

def sanitize_links_and_mentions(text:, unsafe: false, format_html: true)

def sanitize_links_and_mentions(text:, unsafe: false, format_html: true)
  doc = CommonMarker.render_doc(
    text, :LIBERAL_HTML_TAG, COMMONMARKER_EXTENSIONS
  )
  sanitize_team_mentions(doc)
  sanitize_mentions(doc)
  sanitize_links(doc)
  sanitize_nwo_text(doc)
  render_options = if text.match?(MARKDOWN_REGEX)
                     COMMONMARKER_OPTIONS
                   else
                     COMMONMARKER_OPTIONS + [:HARDBREAKS]
                   end
  mode = unsafe ? :UNSAFE : :DEFAULT
  return doc.to_commonmark([mode] + render_options) unless format_html
  doc.to_html(([mode] + render_options), COMMONMARKER_EXTENSIONS)
end

def sanitize_mentions(doc)

def sanitize_mentions(doc)
  doc.walk do |node|
    if node.type == :text &&
       node.string_content.match?(MENTION_REGEX)
      nodes = if parent_node_link?(node)
                build_mention_link_text_nodes(node.string_content)
              else
                build_mention_nodes(node.string_content)
              end
      nodes.each do |n|
        node.insert_before(n)
      end
      node.delete
    end
  end
end

def sanitize_nwo_text(doc)

def sanitize_nwo_text(doc)
  doc.walk do |node|
    if node.type == :text &&
       node.string_content.match?(GITHUB_NWO_REGEX) &&
       !parent_node_link?(node)
      replace_nwo_node(node)
    end
  end
end

def sanitize_team_mentions(doc)

def sanitize_team_mentions(doc)
  doc.walk do |node|
    if node.type == :text &&
       node.string_content.match?(TEAM_MENTION_REGEX)
      nodes = build_team_mention_nodes(node.string_content)
      nodes.each do |n|
        node.insert_before(n)
      end
      node.delete
    end
  end
end