#!/usr/bin/env ruby

require 'net/https'

module REST
  
	class Connection
	
		def initialize(base_url, args = {})
			@base_url = base_url
			@username = args[:username]
			@password = args[:password]
		end

		def request_get(resource, args = nil)
			request(resource, "get", args)
		end

		def request_post(resource, args = nil)
			request(resource, "post", args)
		end

		def request(resource, method = "get", args = nil)
			url = URI.join(@base_url, resource)

			if args
				url.query = args.map { |k,v| "%s=%s" % [URI.encode(k), URI.encode(v)] }.join("&")
			end

			case method
  			when "get"
  				req = Net::HTTP::Get.new(url.request_uri)
  			when "post"
  				req = Net::HTTP::Post.new(url.request_uri)
			end

			if @username and @password
				req.basic_auth(@username, @password)
			end

			http = Net::HTTP.new(url.host, url.port)
      http.use_ssl = (url.port == 443)

			res = http.start() { |conn| conn.request(req) }
			res.body
		end
		
	end
	
end

def print_usage
  puts <<-END
-------------------------------------------------------
service-testscript for the pruefungssekretariat-service
da-op3n 2008 -- ilo
-------------------------------------------------------
usage: test.rb store|retrieve $ip $flag_id $flag
       test.rb test $ip
-------------------------------------------------------
  END
  exit 1
end

def store(url, flag_id, flag)
  
	puts "store #{flag} with #{flag_id} at #{url}"
	
	begin
	  rest = REST::Connection.new(url)
	  exit 0 if rest.request("/flags/store/#{flag_id}/#{flag}") == flag
	rescue StandardError => crash
	  $stderr.puts $!
	end
	
	puts 'fail'
  exit 1

end

def retrieve(url, flag_id, flag)
  
  puts "retrieve #{flag} with #{flag_id}"
  
	begin
	  rest = REST::Connection.new(url)
	  exit 0 if rest.request("/flags/retrieve/#{flag_id}") == flag
	  puts "is not #{flag}"
	  exit 5
	rescue
	  $stderr.puts $!
	end
	
	puts 'fail'
	exit 1
	
end

def test (ip)
  
  puts "testing functionality of service #{ip}"
  
  begin
    rest = REST::Connection.new(ip)
    
    exit 9 unless rest.request("/students") == "Unauthorized"
    exit 9 unless rest.request("/professors") == "Unauthorized"
        
    exit 0
  rescue
    puts $!
    puts 'fail'
    exit 9
  end
  
end

if __FILE__ == $0
  
  functions = {
  	'store' => Kernel.method(:store),
  	'retrieve' => Kernel.method(:retrieve),
  	'test' => Kernel.method(:test) }

  function, ip, flag_id, flag = *ARGV

  print_usage unless ARGV.length == 4 or function == 'test' and functions[function] and ip

  url = ip.dup
  url.insert(0, "http://") unless ip =~ %r{^http://}
  
  functions[function].call(url, flag_id, flag) unless function == 'test'
  test(ip)
  
end