class Tapioca::Static::RequiresCompiler

def collect_files(config)

def collect_files(config)
  config.paths.flat_map do |path|
    path = (Pathname.new(@sorbet_path) / "../.." / path).cleanpath
    if path.directory?
      Dir.glob("#{path}/**/*.rb", File::FNM_EXTGLOB).reject do |file|
        relative_file_path = Pathname.new(file).relative_path_from(path)
        file_ignored_by_sorbet?(config, relative_file_path)
      end
    else
      [path.to_s]
    end
  end.sort.uniq
end

def collect_requires(file_path)

def collect_requires(file_path)
  File.binread(file_path).lines.filter_map do |line|
    /^\s*require\s*(\(\s*)?['"](?<name>[^'"]+)['"](\s*\))?/.match(line) { |m| m["name"] }
  end.reject { |require| require.include?('#{') } # ignore interpolation
end

def compile

def compile
  config = Spoom::Sorbet::Config.parse_file(@sorbet_path)
  files = collect_files(config)
  names_in_project = files.to_h { |file| [File.basename(file, ".rb"), true] }
  files.flat_map do |file|
    collect_requires(file).reject { |req| names_in_project[req] }
  end.sort.uniq.map do |name|
    "require \"#{name}\"\n"
  end.join
end

def file_ignored_by_sorbet?(config, file_path)

def file_ignored_by_sorbet?(config, file_path)
  file_path_parts = path_parts(file_path)
  config.ignore.any? do |ignore|
    # Sorbet --ignore matching method:
    # ---
    # Ignores input files that contain the given
    # string in their paths (relative to the input
    # path passed to Sorbet).
    #
    # Strings beginning with / match against the
    # prefix of these relative paths; others are
    # substring matches.
    # Matches must be against whole folder and file
    # names, so `foo` matches `/foo/bar.rb` and
    # `/bar/foo/baz.rb` but not `/foo.rb` or
    # `/foo2/bar.rb`.
    ignore_parts = path_parts(Pathname.new(ignore))
    file_path_part_sequences = file_path_parts.each_cons(ignore_parts.size)
    # if ignore string begins with /, we only want the first sequence to match
    file_path_part_sequences = [file_path_part_sequences.first].to_enum if ignore.start_with?("/")
    # we need to match whole segments
    file_path_part_sequences.include?(ignore_parts)
  end
end

def initialize(sorbet_path)

def initialize(sorbet_path)
  @sorbet_path = sorbet_path
end

def path_parts(path)

def path_parts(path)
  T.unsafe(path).descend.map { |part| part.basename.to_s }
end