require 'tofu/tofulet'
require 'drb/drb'

class Counter < Tofu::Session
  def initialize(bartender, hint=nil)
    @value = 0
  end

  def service(context)
    case context.req_method
    when 'GET', 'POST', 'HEAD'
      @value += 1 # MT-unsafe
      context.res_header('content-type', 'text/plain')
      context.res_body(@value.to_s)
    else
      context.res_method_not_allowed
    end
  end

  def expires
    case @value
    when 0..10
      nil # never
    when 11..15
      Time.now + 15 # 15 sec
    else
      Time.at(1) # expired
    end
  end
end

class Hello < Tofu::Session
  include MonitorMixin
  def initialize(bartender, hint=nil)
    super(bartender)
    @user = nil
    @expires = nil
    @erb = ERbLight.new(page)
  end

  def page
<<EOP
<html>
<head><title>Hello <%=username%></title></head>
<body>
<p>Hi, <%=username%></p>
<ul>
<% if @user %>
<li><a href="logout">logout</a></li>
<% else %>
<li><a href="seki">seki</a></li>
<li><a href="nahi">nahi</a></li>
<li><a href="gotoyuzo">gotoyuzo</a></li>
<% end %>
</body>
</html>
EOP
  end

  def username
    @user || "guest"
  end

  def service(context)
    case context.req_method
    when 'GET', 'POST', 'HEAD'
      do_GET(context)
    else
      context.res_method_not_allowed
    end
  end

  def do_GET(context)
    context.logger.debug(context.req_path_info)
    if /\/([a-zA-Z]+)/ =~ context.req_path_info	#/
      cmd = $1
    else
      cmd = nil
    end
    synchronize do
      if cmd == "logout"
	@user = nil
      elsif @user.nil? && cmd
	@user = $1 #login!
      end
    end
    context.res_header('content-type', 'text/html')
    context.res_body(@erb.result(binding))
    @expires = Time.now + 30
  end

  def expires
    @expires
  end
end

def setup_tofulet(s)
  s.mount("/counter", WEBrick::Tofulet, Tofu::Bartender.new(Counter))
  s.mount("/hello", WEBrick::Tofulet, Tofu::Bartender.new(Hello))
end

def setup_divlet(s)
  s.mount("/div", 
	  WEBrick::Tofulet, Tofu::Bartender.new(TofuSampleSession))
end

def setup_divlet_drb(s, bartender)
  s.mount("/div", WEBrick::Tofulet, bartender)
end


def main_drb
  DRb.start_service

  bartender = DRbObject.new(nil, 'druby://localhost:7642')

  logger = WEBrick::Log::new($stderr, WEBrick::Log::DEBUG)

  s = WEBrick::HTTPServer.new(:Port => 2000,
			      :AddressFamily => Socket::AF_INET,
			      :BindAddress => ENV['HOSTNAME'],
			      :Logger => logger)

  setup_tofulet(s)
  setup_divlet_drb(s, bartender)

  trap("INT"){ s.shutdown }
  s.start
end

def main
  require 'tofu-app'

  DRb.start_service

  logger = WEBrick::Log::new($stderr, WEBrick::Log::DEBUG)

  s = WEBrick::HTTPServer.new(:Port => 2000,
			      :AddressFamily => Socket::AF_INET,
			      :BindAddress => ENV['HOSTNAME'],
			      :Logger => logger)

  setup_tofulet(s)
  setup_divlet(s)

  trap("INT"){ s.shutdown }
  s.start
end

main

