require 'div'
require 'singleton'
require 'RAA'; include RAA
require 'soap/driver'
require 'devel/logger'
require 'hotpage'
require 'mutexm'

class RAADiv < Div::Div
  include Singleton
  include MutexM

  attr_accessor :server
  attr_accessor :proxy
  attr_accessor :size

  DefaultRAAServer = 'http://www.ruby-lang.org/~nahi/soap/raa/'

  InitialCoverSec = 7 * 24 * 3600	# 1 week
  CoverSec = 30 * 60			# 30 min
  UpdateInterval = 5 * 60		# 5 min

  def initialize
    @size = 10
    @session = nil
    @div_class = type.to_s
    @div_id = self.id.to_s
    @action = nil

    @server = DefaultRAAServer
    @proxy = nil
    @raa = RAA::Driver.new( @server, @proxy )
    @raa.setLogDev( '/var/tmp/raa-div.log' )
    @raa.setLogLevel( Devel::Logger::INFO )
    @hotItemPool = HotPage.new( &self.method( :hotOrder ))

    @t = Thread.new { poll }
  end

  def to_html(context)
    "<table border='0' width='100%' cellpadding='0' cellspacing='3'>\n" <<
    "<tr><th><small>" <<
    "<a href=\"http://www.ruby-lang.org/en/raa.html\">RAA</a>" <<
    "</small></th></tr>\n" <<
      hotitem.collect { | info |
	productName = info.product.name
	version = info.product.version
	author = info.owner.name
	d = info.update
        category = info.category.to_s.sub(/^Application/, 'App').sub(/^Library/, 'Lib').sub(/^Documentation/, 'Doc')
	t = Time.gm( d.year, d.mon, d.mday, d.hour, d.min, d.sec ).localtime
	update = format( '%02d-%02dT%02d:%02d', t.mon, t.mday, t.hour, t.min )
        title = "by #{ author }, #{ update }"
	<<__HERE__
<tr><td><small><a href="http://www.ruby-lang.org/en/raa-list.rhtml?name=#{ u( productName ) }" title='#{ h(title) }'>#{ h(productName) }</a> #{ h(version) } [#{ h(category) }]</small></td></tr>
__HERE__
      }.join( "" ) <<
    "</table>\n"
  end

private

  def hotitem
    synchronize do
      @hotItemPool.pages[ 0, @size ]
    end
  end

  def poll
    milestone = Time.at( Time.now.gmtime - InitialCoverSec )
    while true
      begin
	t = milestone
	milestone = Time.at( Time.now.gmtime - CoverSec )
	items = begin
	    @raa.getModifiedInfoSince( t )
	  rescue HTTPAccess2::Session::BadResponse
	    # Try again.
	    @raa.getModifiedInfoSince( t )
	  end
	synchronize do
	  oldItems = @hotItemPool.__pages
	  items.each do |item|
	    old = oldItems.find { |i| i.eql?( item ) }
	    if old
	      @hotItemPool.delete( old )
	    end
	    @hotItemPool << item
	  end
	end
	@raa.log.info "Got #{ items.size } items."
      rescue Exception
	@raa.log.fatal $!
      end
      sleep UpdateInterval
    end
  end

  def hotOrder( a, b )
    b.update <=> a.update
  end
end

if __FILE__ == $0
  a = RAADiv.instance
  while true
    p a.to_html(nil)
    sleep 10
  end
end

