class Selenium::Server

def self.get(required_version, opts = {})

def self.get(required_version, opts = {})
  new(download(required_version), opts)
end

def <<(arg)

def <<(arg)
  if arg.is_a?(Array)
    @additional_args += arg
  else
    @additional_args << arg.to_s
  end
end

def download(required_version)

def download(required_version)
  required_version = latest if required_version == :latest
  download_file_name = "selenium-server-standalone-#{required_version}.jar"
  return download_file_name if File.exist? download_file_name
  begin
    open(download_file_name, 'wb') do |destination|
      net_http.start('selenium-release.storage.googleapis.com') do |http|
        resp = http.request_get("/#{required_version[/(\d+\.\d+)\./, 1]}/#{download_file_name}") do |response|
          total = response.content_length
          progress = 0
          segment_count = 0
          response.read_body do |segment|
            progress += segment.length
            segment_count += 1
            if segment_count % 15 == 0
              percent = (progress.to_f / total.to_f) * 100
              print "#{CL_RESET}Downloading #{download_file_name}: #{percent.to_i}% (#{progress} / #{total})"
              segment_count = 0
            end
            destination.write(segment)
          end
        end
        unless resp.is_a? Net::HTTPSuccess
          raise Error, "#{resp.code} for #{download_file_name}"
        end
      end
    end
  rescue
    FileUtils.rm download_file_name if File.exist? download_file_name
    raise
  end
  download_file_name
end

def initialize(jar, opts = {})

def initialize(jar, opts = {})
  raise Errno::ENOENT, jar unless File.exist?(jar)
  @jar        = jar
  @host       = '127.0.0.1'
  @port       = opts.fetch(:port, 4444)
  @timeout    = opts.fetch(:timeout, 30)
  @background = opts.fetch(:background, false)
  @log        = opts[:log]
  @additional_args = []
end

def latest

def latest
  require 'rexml/document'
  net_http.start('selenium-release.storage.googleapis.com') do |http|
    REXML::Document.new(http.get('/').body).root.get_elements('//Contents/Key').map do |e|
      e.text[/selenium-server-standalone-(\d+\.\d+\.\d+)\.jar/, 1]
    end.compact.max
  end
end

def net_http

def net_http
  http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
  if http_proxy
    http_proxy = "http://#{http_proxy}" unless http_proxy.start_with?('http://')
    uri = URI.parse(http_proxy)
    Net::HTTP::Proxy(uri.host, uri.port)
  else
    Net::HTTP
  end
end

def poll_for_service

def poll_for_service
  return if socket.connected?
  raise Error, "remote server not launched in #{@timeout} seconds"
end

def poll_for_shutdown

def poll_for_shutdown
  return if socket.closed?
  raise Error, "remote server not stopped in #{@timeout} seconds"
end

def process

def process
  @process ||= (
    # extract any additional_args that start with -D as options
    properties = @additional_args.dup - @additional_args.delete_if { |arg| arg[/^-D/] }
    server_command = ['java'] + properties + ['-jar', @jar, '-port', @port.to_s] + @additional_args
    cp = ChildProcess.build(*server_command)
    WebDriver.logger.debug("Executing Process #{server_command}")
    io = cp.io
    if @log.is_a?(String)
      @log_file = File.open(@log, 'w')
      io.stdout = io.stderr = @log_file
    elsif @log
      io.inherit!
    end
    cp.detach = @background
    cp
  )
end

def socket

def socket
  @socket ||= WebDriver::SocketPoller.new(@host, @port, @timeout)
end

def start

def start
  process.start
  poll_for_service
  process.wait unless @background
end

def stop

def stop
  begin
    Net::HTTP.get(@host, '/selenium-server/driver/?cmd=shutDownSeleniumServer', @port)
  rescue Errno::ECONNREFUSED
  end
  stop_process if @process
  poll_for_shutdown
  @log_file.close if @log_file
end

def stop_process

def stop_process
  return unless @process.alive?
  begin
    @process.poll_for_exit(5)
  rescue ChildProcess::TimeoutError
    @process.stop
  end
rescue Errno::ECHILD
  # already dead
ensure
  @process = nil
end

def webdriver_url

def webdriver_url
  "http://#{@host}:#{@port}/wd/hub"
end