class DEBUGGER__::Config

def self.parse_argv argv

def self.parse_argv argv
  config = {
    mode: :start,
    no_color: (nc = ENV['NO_COLOR']) && !nc.empty?,
  }
  CONFIG_MAP.each{|key, evname|
    if val = ENV[evname]
      config[key] = parse_config_value(key, val)
    end
  }
  return config if !argv || argv.empty?
  if argv.kind_of? String
    require 'shellwords'
    argv = Shellwords.split(argv)
  end
  require 'optparse'
  require_relative 'version'
  have_shown_version = false
  opt = OptionParser.new do |o|
    o.banner = "#{$0} [options] -- [debuggee options]"
    o.separator ''
    o.version = ::DEBUGGER__::VERSION
    o.separator 'Debug console mode:'
    o.on('-n', '--nonstop', 'Do not stop at the beginning of the script.') do
      config[:nonstop] = '1'
    end
    o.on('-e DEBUG_COMMAND', 'Execute debug command at the beginning of the script.') do |cmd|
      config[:commands] ||= ''
      config[:commands] += cmd + ';;'
    end
    o.on('-x FILE', '--init-script=FILE', 'Execute debug command in the FILE.') do |file|
      config[:init_script] = file
    end
    o.on('--no-rc', 'Ignore ~/.rdbgrc') do
      config[:no_rc] = true
    end
    o.on('--no-color', 'Disable colorize') do
      config[:no_color] = true
    end
    o.on('--no-sigint-hook', 'Disable to trap SIGINT') do
      config[:no_sigint_hook] = true
    end
    o.on('-c', '--command', 'Enable command mode.',
                            'The first argument should be a command name in $PATH.',
                            'Example: \'rdbg -c bundle exec rake test\'') do
      config[:command] = true
    end
    o.separator ''
    o.on('-O', '--open=[FRONTEND]', 'Start remote debugging with opening the network port.',
                                    'If TCP/IP options are not given, a UNIX domain socket will be used.',
                                    'If FRONTEND is given, prepare for the FRONTEND.',
                                    'Now rdbg, vscode and chrome is supported.') do |f|
      case f # some format patterns are not documented yet
      when nil
        config[:open] = true
      when /\A\d\z/
        config[:open] = true
        config[:port] = f.to_i
      when /\A(\S+):(\d+)\z/
        config[:open] = true
        config[:host] = $1
        config[:port] = $2.to_i
      when 'tcp'
        config[:open] = true
        config[:port] ||= 0
      when 'vscode', 'chrome', 'cdp'
        config[:open] = f&.downcase
      else
        raise "Unknown option for --open: #{f}"
      end
    end
    o.on('--sock-path=SOCK_PATH', 'UNIX Domain socket path') do |path|
      config[:sock_path] = path
    end
    o.on('--port=PORT', 'Listening TCP/IP port') do |port|
      config[:port] = port
    end
    o.on('--host=HOST', 'Listening TCP/IP host') do |host|
      config[:host] = host
    end
    o.on('--cookie=COOKIE', 'Set a cookie for connection') do |c|
      config[:cookie] = c
    end
    o.on('--session-name=NAME', 'Session name') do |name|
      config[:session_name] = name
    end
    rdbg = 'rdbg'
    o.separator ''
    o.separator '  Debug console mode runs Ruby program with the debug console.'
    o.separator ''
    o.separator "  '#{rdbg} target.rb foo bar'                starts like 'ruby target.rb foo bar'."
    o.separator "  '#{rdbg} -- -r foo -e bar'                 starts like 'ruby -r foo -e bar'."
    o.separator "  '#{rdbg} -c rake test'                     starts like 'rake test'."
    o.separator "  '#{rdbg} -c -- rake test -t'               starts like 'rake test -t'."
    o.separator "  '#{rdbg} -c bundle exec rake test'         starts like 'bundle exec rake test'."
    o.separator "  '#{rdbg} -O target.rb foo bar'             starts and accepts attaching with UNIX domain socket."
    o.separator "  '#{rdbg} -O --port 1234 target.rb foo bar' starts accepts attaching with TCP/IP localhost:1234."
    o.separator "  '#{rdbg} -O --port 1234 -- -r foo -e bar'  starts accepts attaching with TCP/IP localhost:1234."
    o.separator "  '#{rdbg} target.rb -O chrome --port 1234'  starts and accepts connecting from Chrome Devtools with localhost:1234."
    o.separator ''
    o.separator 'Attach mode:'
    o.on('-A', '--attach', 'Attach to debuggee process.') do
      config[:mode] = :attach
    end
    o.separator ''
    o.separator '  Attach mode attaches the remote debug console to the debuggee process.'
    o.separator ''
    o.separator "  '#{rdbg} -A'           tries to connect via UNIX domain socket."
    o.separator "  #{' ' * rdbg.size}                If there are multiple processes are waiting for the"
    o.separator "  #{' ' * rdbg.size}                debugger connection, list possible debuggee names."
    o.separator "  '#{rdbg} -A path'      tries to connect via UNIX domain socket with given path name."
    o.separator "  '#{rdbg} -A port'      tries to connect to localhost:port via TCP/IP."
    o.separator "  '#{rdbg} -A host port' tries to connect to host:port via TCP/IP."
    o.separator ''
    o.separator 'Other options:'
    o.on('-v', 'Show version number') do
      puts o.ver
      have_shown_version = true
    end
    o.on('--version', 'Show version number and exit') do
      puts o.ver
      exit
    end
    o.on("-h", "--help", "Print help") do
      puts o
      exit
    end
    o.on('--util=NAME', 'Utility mode (used by tools)') do |name|
      require_relative 'client'
      Client.util(name)
      exit
    end
    o.on('--stop-at-load', 'Stop immediately when the debugging feature is loaded.') do
      config[:stop_at_load] = true
    end
    o.separator ''
    o.separator 'NOTE'
    o.separator '  All messages communicated between a debugger and a debuggee are *NOT* encrypted.'
    o.separator '  Please use the remote debugging feature carefully.'
  end
  opt.parse!(argv)
  if argv.empty?
    case
    when have_shown_version && config[:mode] == :start
      exit
    end
  end
  config
end