require 'rubygems'
require 'mechanize'
require 'gserver'
require 'logger'
require 'yaml'

CONFIG = {
  :email => "",
  :password => "",
  
  #:street => nil,
  #:street_number => nil,
  #:postcode => nil,
  #:city => "Gent"
  :directory => "/home/joren/Desktop/pizza_service"
  :tcp_port => 6666,
  :logger => Logger.new('/home/joren/Desktop/pizza_service/pizza_server.log', 'monthly'),
  :production => false,
  
	:restaurants => { 
		:mario => {
			:key => 'restaurants-pizza-mario-gent', #url name
			:margherita_big => 10198, # 6.00 EUR
			:hawaii_big => 10216, # 7.50 EUR
			:hawaii_normal => 10215, # 6.00 EUR
			:veggie_normal => 10235 # 7.00 EUR
		},
		:express => {
			:key => 'restaurants-pizza-express', #url name
			:primavera => 385 # pepers, ajuin, champignons en artisjok 7.50 EUR
		}
	}
}


class PizzaServer < GServer
    def initialize()
      super(CONFIG[:tcp_port], '*', 4 , $stderr , true)
      @log_file = CONFIG[:logger]
    end
    
    def serve(io)
      contents = ""
      begin
        contents= io.gets.strip
        order_hash =  YAML::load( contents)
        restaurant = order_hash.keys.first.to_sym
        pizzas = order_hash[order_hash.keys.first].map{|p| p.to_sym}
        
        #check order
        raise "Unknown restaurant #{restaurant}" unless CONFIG[:restaurants][restaurant]
        restaurant_pizzas = CONFIG[:restaurants][restaurant].keys
        unless  (restaurant_pizzas - pizzas).size == (restaurant_pizzas.size - pizzas.size)
          raise "Unknown pizza(s): #{(pizzas - restaurant_pizzas).join(",")} for restaurant #{restaurant}" 
        end
        
        log "Order received for restaurant #{restaurant}, pizza(s) #{pizzas.join(",")}" 
        PizzaOrder.new(restaurant,pizzas).order
        io.puts "OK"
        io.close
      rescue Exception => message
        log "Failed to process #{contents} : #{message.to_s}"
        io.puts "Failed to order pizza: #{message.to_s}" 
      end
    end
    
    def log(msg)
        @log_file.info(msg)
    end
end
  
class PizzaOrder
  
  def initialize(restaurant,pizzas)
    @restaurant = restaurant
    @pizzas =  pizzas
  end
  
  def order()    
    login_url = "http://www.just-eat.be/pages/member/login.aspx"
    #a = WWW::Mechanize.new{|a| a.log = Logger.new(STDERR) }
    a = WWW::Mechanize.new
    a.get(login_url) do |login_page|   
      #post login_form
      login_form = login_page.forms.first
      login_form.txtUser = CONFIG[:email]
      login_form.txtPass  = CONFIG[:password] 
      a.submit(login_form, login_form.buttons[1])

      restaurant_url = "http://www.just-eat.be/#{CONFIG[:restaurants][@restaurant][:key]}/menu"
      #put pizzas in cart
      @pizzas.each do |pizza_symbol|
        pizza_id = CONFIG[:restaurants][@restaurant][pizza_symbol]
        restaurant_page = a.get(restaurant_url)
        restaurant_form = restaurant_page.forms.first
        restaurant_form['__EVENTTARGET'] = 'ctl00_Basket_UpdatePanel1'
        restaurant_form['__EVENTARGUMENT']= pizza_id.to_s + '#0#0#"'
        restaurant_form.submit
      end
      
      #process cart
      restaurant_page = a.get(restaurant_url)
      order_now_form = restaurant_page.forms.first
      order_now_button =  order_now_form.button_with(:value =>  "Bestel nu >>") 
      a.submit(order_now_form,order_now_button)
      
      #change address if requested
      order_details_page =  a.get("http://www.just-eat.be/order-details")
      order_details_form = order_details_page.forms.first
      order_details_form["ctl00$ContentPlaceHolder1$ctl01$txtVej"] = CONFIG[:street] if CONFIG[:street] 
      order_details_form["ctl00_ContentPlaceHolder1_ctl01_txtHusnummer"] = CONFIG[:street_number] if CONFIG[:street_number] 
      order_details_form["ctl00$ContentPlaceHolder1$ctl01$txtPostnummer"] = CONFIG[:postcode] if CONFIG[:postcode] 
      order_details_form["ctl00$ContentPlaceHolder1$ctl01$txtBy"] = CONFIG[:city] if CONFIG[:city] 
      
      #confirm page, choose payment (cash on delivery) and delivery options
      confirm_order_page = a.submit(order_details_form,order_details_form.button_with(:value => "Verder >>"))
      confirm_order_form = confirm_order_page.forms.first	
      pay_on_delivery_button = confirm_order_form.buttons.select{|button| button.name =~ /DKPayUponDlv/}[0]
      pay_on_delivery_select = confirm_order_form.fields.select{|field| field.name =~ /ddCardTypes/}[0]    
      pay_on_delivery_select.value = "cash_cash"
      
      #do order in production mode
      if CONFIG[:production]
        #go to the intermediate do payment page
        order_do_payment_page = a.submit(confirm_order_form,pay_on_delivery_button)
        #submit the intermediate page and go to the review page
        order_review_page = a.submit(order_do_payment_page.forms.first)
      else 
        #puts html to review order
        puts confirm_order_page.body
      end
    end #end 
    
  end #end order
  
end #end class

server = PizzaServer.new
server.start

loop do
    sleep 20
    break if server.stopped?
end





