# Copyright (C) 2003-2005 Kouichirou Eto, All rights reserved.

$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
require "qwik/sitemonitor"
require "qwik/qp"

module Qwik
  class Action
    def c_monitor(cmd)
      ev = {}
      ev[:title] = "Event occured."
      ev[:cmd] = cmd.to_s
      ev[:pagename] = @req.base
      @site.sitemonitor.shout(ev)
    end

    def monitor_ok(ev)
      ar = [:event]
      ar << [:title, ev[:title]] if ev[:title]
      ar << [:cmd, ev[:cmd]] if ev[:cmd]
      ar << [:pagename, ev[:pagename]] if ev[:pagename]
      @res.status = 200
      @res.body = ar
    end

    def ext_monitor
      #qp @req.base+".monitor"
      mon = @site.sitemonitor # connect to Update Monitor
      mon.listen {|ev| # wait for update
	#qp ev
	next if ev[:pagename] != @req.base

	if ev[:cmd] == "save"
	  #qp "save event!", ev
	  #qp "save event!", @site, @req.base
	  page = @site[@req.base]
	  #qp page
	  str = page.get_body
	  #qp str
	  #w = c_parse(str) # without resolve
	  w = c_res(str)
	  tres = TDiaryResolver.new(@config, @site, self)
	  w = tres.resolve(w)
	  #qp w
	  if ! $debug
	    w = w.format_xml
	    w = w.sjistou8
	  end
	  @res.status = 200
	  @res["Cache-Control"] = "no-cache, must-revalidate"
	  @res["Pragma"] = "no-cache"
	  @res.body = w
	  #qp "monitor return ", w
	  #qp "monitor return"
	  return
	end
      }
    end

    def plg_monitor(pagename=@req.base)
      script = "
g_monitor_env.add('#{pagename}');
g_monitor_env.start();
"
      #puts script
      w = [:div, {:id=>"monitor"}]
      w << "monitor(#{pagename})" if $debug
      w << [:script,{:type=>"text/javascript",:src=>".theme/js/monitor.js"},""]
      w << [:script, {:type=>"text/javascript"}, script]
      #pp w
      return w
    end

    # for test
    def act_viewmonitor
      return c_notice("monitor")
    end
  end

  class Event
    def initialize
    end
  end
end

if $0 == __FILE__
  require "t/test"
  $KCODE = "s"
  $debug = true
end

if $debug
  class TC_ActMonitor < Test::Unit::TestCase
    include TestSession

    def test_act_monitor
      return if $0 != __FILE__	# just only for unit test.

      Thread.abort_on_exception = true
      t_add_user
      page = @site.create_new
      page.store("*t")

      t = Thread.new {
	#sleep 0.5
	sleep 0.1
	tres = session("/test/1.save?contents=t2")
	assert_text("Page is saved.", "title", tres)
      }

      res = session("/test/1.monitor") # block
      assert_xml([:p, "t2"], "//div[@class='section']", res)

      t.join # Wait end of thread.
    end

    def test_several_monitors
      return if $0 != __FILE__	# just only for unit test.

      Thread.abort_on_exception = true
      t_add_user
      page = @site["_SiteMember"]
      assert_equal(",user@e.com,\n", page.load)

      page = @site.create_new
      page.store("*t")

      sleep 0.1

      t1 = Thread.new {
	t1res = session("/test/1.monitor") # block
	assert_xml([:p, "t3"], "//div[@class='section']", t1res)
      }

      t2 = Thread.new {
	t2res = session("/test/1.monitor") # block
	assert_xml([:p, "t3"], "//div[@class='section']", t2res)
      }

      #sleep 0.5
      sleep 0.1
      tres = session("/test/1.save?contents=t3")
      assert_text("Page is saved.", "title", tres)

      t1.join # Wait end of thread.
      t2.join # Wait end of thread.
    end

    def test_many_monitors
      return if $0 != __FILE__	# just only for unit test.

      Thread.abort_on_exception = true
      t_add_user
      page = @site.create_new
      page.store("*t")

      ts = []
      res = []
      max = 5

      (0..max).each {|i|
	ts[i] = Thread.new {
	  res[i] = session("/test/1.monitor") # block
	  assert_xml([:p, "t3"], "//div[@class='section']", res[i])
	}
      }

      #sleep 0.5
      sleep 0.1
      tres = session("/test/1.save?contents=t3")
      assert_text("Page is saved.", "title", tres)

      (0..max).each {|i|
	ts[i].join # Wait end of thread.
      }
    end
  end
end
