require 'httpclient'

require 'celluloid'
require 'connection_pool'

require 'uri'

require 'active_support/core_ext'
require 'openssl'

class Signup
  URL = 'https://flexo.3scale.net/p/signup'

  @@pool = ConnectionPool.new(:size => 5, :timeout => 2.minutes) do
    HTTPClient.new.tap do |client|
        client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
  end

  include Celluloid

  attr_accessor :retryable

  def initialize(seed, id, options)
    @id = id
    @seed = seed
    @url = options[:url] || URL
  end

  def params
    {
      # "format" => 'json',
      "account" => {
        "org_name"=>"#{@seed}-#{@id}",
        "subdomain"=>"#{@seed}-#{@id}",
        "user" => {
          "first_name" => "John #{@id}",
          "last_name"=>"Doe #{@id}",
          "email"=>"M8R-9l9tp3@mailinator.com",
          "username"=>"user",
          "password"=>"password",
          "password_confirmation" => "password"
        }
      }
    }
  end

  def post
    @@pool.with do |client|
      perform(client)
    end
  end

  class InvalidResponseError < StandardError; end

  private

  def perform(client)
    time = Time.now
    response = client.post(@url, params.to_query)

    if response.status == 302
      print "#{@id} DONE in #{Time.now - time} seconds\n"
    else
      raise InvalidResponseError.new(response.status)
    end
  rescue InvalidResponseError
    print "#{@id} ERROR (#{response.status}) in #{Time.now - time} seconds."
    if retryable
      sleep 1
      retry
    end
  rescue HTTPClient::BadResponseError
    print "#{@id} ERROR in #{Time.now - time} seconds\n"
  rescue HTTPClient::ReceiveTimeoutError
    print "#{@id} TIMEOUT in #{Time.now - time} seconds\n"
  rescue OpenSSL::SSL::SSLError
    print "#{@id} SSL ERROR in #{Time.now - time} seconds\n"
  end
end
