class RubyMemcheck::TestTaskReporter

def initialize(configuration)

def initialize(configuration)
  @configuration = configuration
  @loaded_binaries = nil
end

def loaded_binaries

def loaded_binaries
  return @loaded_binaries if @loaded_binaries
  loaded_features = File.readlines(configuration.loaded_features_file, chomp: true)
  @loaded_binaries = loaded_features.keep_if do |feat|
    # Keep only binaries (ignore Ruby files).
    File.extname(feat) == ".so"
  end.freeze
  @loaded_binaries
end

def output_valgrind_errors

def output_valgrind_errors
  @errors.each do |error|
    configuration.output_io.puts error
    configuration.output_io.puts
  end
end

def parse_valgrind_output

def parse_valgrind_output
  require "nokogiri"
  @errors = []
  valgrind_xml_files.each do |file|
    reader = Nokogiri::XML::Reader(File.open(file)) do |config| # rubocop:disable Style/SymbolProc
      config.huge
    end
    reader.each do |node|
      next unless node.name == "error" && node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT
      error_xml = Nokogiri::XML::Document.parse(node.outer_xml).root
      error = ValgrindError.new(configuration, loaded_binaries, error_xml)
      next if error.skip?
      @errors << error
    end
  end
end

def remove_valgrind_xml_files

def remove_valgrind_xml_files
  valgrind_xml_files.each do |file|
    File.delete(file)
  end
end

def report_valgrind_errors

def report_valgrind_errors
  parse_valgrind_output
  remove_valgrind_xml_files
  unless errors.empty?
    output_valgrind_errors
    raise VALGRIND_REPORT_MSG
  end
end

def run_ruby_with_valgrind(&block)

def run_ruby_with_valgrind(&block)
  setup
  yield
  report_valgrind_errors
end

def setup

def setup
  ENV["RUBY_MEMCHECK_LOADED_FEATURES_FILE"] = File.expand_path(configuration.loaded_features_file)
  ENV["RUBY_MEMCHECK_RUNNING"] = "1"
end

def valgrind_xml_files

def valgrind_xml_files
  @valgrind_xml_files ||= Dir[File.join(configuration.temp_dir, "*.xml")].freeze
end