#!/usr/bin/env ruby

require "bundler/setup"
require "optparse"
require "rbs"
require "rbs/annotate"

source = RBS::Annotate::RDocSource.new()
annotator = RBS::Annotate::RDocAnnotator.new(source: source)

OptionParser.new do |opts|
  opts.on("--[no-]system", "Load RDoc from system (defaults to true)") {|b| source.with_system_dir = b }
  opts.on("--[no-]gems", "Load RDoc from gems (defaults to false)") {|b| source.with_gems_dir = b }
  opts.on("--[no-]site", "Load RDoc from site directory (defaults to false)") {|b| source.with_site_dir = b }
  opts.on("--[no-]home", "Load RDoc from home directory (defaults to false)") {|b| source.with_home_dir = b }
  opts.on("-d", "--dir DIRNAME", "Load RDoc from DIRNAME") {|d| source.extra_dirs << Pathname(d) }
  opts.on("--[no-]arglists", "Generate arglists section (defaults to true)") {|b| annotator.include_arg_lists = b }
  opts.on("--[no-]filename", "Include source file name in the documentation (defaults to true)") {|b| annotator.include_filename = b }
end.parse!(ARGV)

tester = Object.new.tap do |object|
  object.singleton_class.define_method(:test_path) {|*| true }
end

name = ARGV.shift or return

source.load()

case
when match = name.match(/(?<constant_name>[^#]+)#(?<method_name>.+)/)
  type_name = RBS::TypeName.parse(match[:constant_name] || raise)
  instance_method = (match[:method_name] or raise).to_sym

  doc = annotator.doc_for_method(type_name, instance_method: instance_method, tester: tester)
when match = name.match(/(?<constant_name>[^#]+)\.(?<method_name>.+)/)
  type_name = RBS::TypeName.parse(match[:constant_name] || raise)
  singleton_method = (match[:method_name] or raise).to_sym

  doc = annotator.doc_for_method(type_name, singleton_method: singleton_method, tester: tester)
else
  type_name = RBS::TypeName.parse(name)

  doc = annotator.doc_for_class(type_name, tester: tester) || annotator.doc_for_constant(type_name, tester: tester)
end

if doc
  puts doc
else
  puts "🤯 Cannot find the definition of `#{name}`"
end
