class DEBUGGER__::UI_TcpServer

def accept

def accept
  retry_cnt = 0
  super # for fork
  begin
    Socket.tcp_server_sockets @host, @port do |socks|
      @local_addr = socks.first.local_address # Change this part if `socks` are multiple.
      rdbg = File.expand_path('../../exe/rdbg', __dir__)
      DEBUGGER__.warn "Debugger can attach via TCP/IP (#{@local_addr.inspect_sockaddr})"
      if @port_save_file
        File.write(@port_save_file, "#{socks[0].local_address.ip_port.to_s}\n")
        DEBUGGER__.warn "Port is saved into #{@port_save_file}"
      end
      DEBUGGER__.info <<~EOS
      With rdbg, use the following command line:
      #
      #   #{rdbg} --attach #{@local_addr.ip_address} #{@local_addr.ip_port}
      #
      EOS
      case CONFIG[:open]
      when 'chrome'
        chrome_setup
      when 'vscode'
        vscode_setup @local_addr.inspect_sockaddr
      end
      Socket.accept_loop(socks) do |sock, client|
        @client_addr = client
        yield @sock_for_fork = sock
      end
    end
  rescue Errno::EADDRINUSE
    if retry_cnt < 10
      retry_cnt += 1
      sleep 0.1
      retry
    else
      raise
    end
  rescue Terminate
    # OK
  rescue => e
    $stderr.puts e.inspect, e.message
    pp e.backtrace
    exit
  end
ensure
  @sock_for_fork = nil
  if @port_save_file && File.exist?(@port_save_file)
    File.unlink(@port_save_file)
  end
end

def chrome_setup

def chrome_setup
  require_relative 'server_cdp'
  @uuid = SecureRandom.uuid
  @chrome_pid = UI_CDP.setup_chrome(@local_addr.inspect_sockaddr, @uuid)
  DEBUGGER__.warn <<~EOS
    With Chrome browser, type the following URL in the address-bar:
       devtools://devtools/bundled/inspector.html?v8only=true&panel=sources&ws=#{@local_addr.inspect_sockaddr}/#{@uuid}
    EOS
end

def initialize host: nil, port: nil

def initialize host: nil, port: nil
  @local_addr = nil
  @host = host || CONFIG[:host]
  @port_save_file = nil
  @port = begin
    port_str = (port && port.to_s) || CONFIG[:port] || raise("Specify listening port by RUBY_DEBUG_PORT environment variable.")
    case port_str
    when /\A\d+\z/
      port_str.to_i
    when /\A(\d+):(.+)\z/
      @port_save_file = $2
      $1.to_i
    else
      raise "Specify digits for port number"
    end
  end
  @uuid = nil # for CDP
  super()
end