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

$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
require "qwik/config"
require "qwik/farm"
require "qwik/mail"
require "qwik/util-path"

module Qwik
  class SendReportThread
    def initialize(config, memory)
      @config, @memory = config, memory
      @report = SendReport.new(@config, @memory)
    end

    def start
      loop {
	sleep(calc_sleep_time(Time.now))
	begin
	  process
	rescue Exception => e
	  p e
	end
      }
    end
  end

  class WeeklySendReportThread < SendReportThread
    def calc_sleep_time(w)
      t = Time.at(w.to_i + 60*60*24*7) # next week
      x = Time.local(t.year, t.mon, t.day, 0, 0, 0, 0) # next
      (x - w).to_i
    end

    def process
      @report.send("weekly")
    end
  end

  class DailySendReportThread < SendReportThread
    def calc_sleep_time(w)
      t = Time.at(w.to_i + 60*60*24) # next day
      x = Time.local(t.year, t.mon, t.day, 0, 0, 0, 0) # next
      (x - w).to_i
    end

    def process
      @report.send("daily")
    end
  end

  class HourlySendReportThread < SendReportThread
    def calc_sleep_time(w)
      t = Time.at(w.to_i + 60*60) # next hour
      x = Time.local(t.year, t.mon, t.day, t.hour, 0, 0, 0) # next
      (x - w).to_i
    end

    def process
      @report.send("hourly")
    end
  end

  class SendReport
    def initialize(config, memory)
      @config, @memory = config, memory
      @farm = @memory.farm
      @key = "_SiteChanged"
    end

    def send(interval)
#      qp interval
      @farm.each {|sitename|
#	qp sitename
	#site = @farm[sitename] # ここがバグってた!
	site = @farm.get_site(sitename)
	if site.siteconfig["reportmail"] == interval
#	  qp "do send_site", sitename
	  send_site(site)
	end
      }
    end

    def send_site(site)
      rep = make_report(site)
#      qp "rep is", rep
      return nil if rep.nil?
      list = site.member.list(false) # not obfuscate
#      qp "list is", list

      list.each {|user|
	mail = generate_report_mail(site, user, rep)
	sendmail = Sendmail.new(@config)
	begin
	  sendmail.sendmail(mail)
	rescue => e
	  qp "error "+e
	end
      }
      site.delete(@key) # destructive
    end

    def make_report(site)
      page = site[@key]
      return nil if page.nil?

      report = ""
      page.wikidb.array.each {|k, v|
	user, cmd, pagename = v
	user = "anonymous" if user.nil? || user == ""
	user = MailAddress.new(user).obfuscate if user != ""
	time = Time.at(k.to_i)
	report += time.strftime("%H:%M")+" "+user+" "+cmd+" "+site.url(pagename)+"\n"
      }
      report
    end

    def generate_report_mail(site, user, rep)
      domainurl = site.domainurl
      siteurl = site.url
      f = site.siteconfig["reportfrom"]
      from = site.ml
      from = f if f && f != ""
      mail = Mail.new
      mail.from = from
      mail.to = user
      mail.subject = siteurl+" レポート"
      mail.content = "#{siteurl} における、本日の編集記録です。\n\n#{rep}"
#      mail.content += "\n\nこのメールを送られないようにするためには，設定ページにアクセスしてください．\n"
#      mail.content += "#{siteurl}/_SiteConfig.html\n"
#     mail.content += "----\nこのメールはqwikWebサーバが自動生成したものです。"
      mail
    end
  end
end

if $0 == __FILE__
  require "qwik/test-common"
  $debug = true
end

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

    def test_all
      # test_weekly_thread
      @day = Qwik::WeeklySendReportThread.new(@config, @memory)
      t = Time.now
      assert_equal(true, 0 < @day.calc_sleep_time(t))
      t = Time.local(2000, 1, 1, 0, 0, 0) # 2000-01-01T00:00:00
      assert_equal(86400*7, @day.calc_sleep_time(t))
      t = Time.local(2000, 1, 1, 0, 30, 0) # 2000-01-01T00:30:00
      assert_equal(603000, @day.calc_sleep_time(t))

      # test_daily_thread
      @day = Qwik::DailySendReportThread.new(@config, @memory)
      t = Time.now
      assert_equal(true, 0 < @day.calc_sleep_time(t))
      t = Time.local(2000, 1, 1, 0, 0, 0) # 2000-01-01T00:00:00
      assert_equal(86400, @day.calc_sleep_time(t))
      t = Time.local(2000, 1, 1, 0, 30, 0) # 2000-01-01T00:30:00
      assert_equal(84600, @day.calc_sleep_time(t))

      # test_hourly_thread
      @day = Qwik::HourlySendReportThread.new(@config, @memory)
      t = Time.now
      assert_equal(true, 0 < @day.calc_sleep_time(t))
      t = Time.local(2000, 1, 1, 0, 0, 0) # 2000-01-01T00:00:00
      assert_equal(3600, @day.calc_sleep_time(t))
      t = Time.local(2000, 1, 1, 0, 30, 0) # 2000-01-01T00:30:00
      assert_equal(1800, @day.calc_sleep_time(t))
    end
  end

  class TC_Report < Test::Unit::TestCase
    include TestSession

    def test_report
      t_add_user

      @report = Qwik::SendReport.new(@config, @memory)
      mail = @report.generate_report_mail(@site, "user@e.com", "test")
      assert_equal("test@example.com", mail.from)
      assert_equal("user@e.com", mail.to)
      assert_equal("http://example.com/test/ レポート", mail.subject)
      assert_equal("http://example.com/test/ における、本日の編集記録です。\n\ntest", mail.content)

      rep = @report.make_report(@site)
      assert_equal(nil, rep)

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

      sitelog = @site.sitelog
      sitelog.add(0, "user@e.com", "save", "1")
      assert_equal(",0,user@e.com,save,1\n", @site["_SiteChanged"].load)
      sitelog.add(0, nil, "save", "1")
      assert_equal(",0,user@e.com,save,1\n,0,,save,1\n",
		   @site["_SiteChanged"].load)

      page = @site["_SiteChanged"]
      rep = @report.make_report(@site)
      assert_equal("09:00 user@e... save http://example.com/test/1.html\n09:00 anonymous save http://example.com/test/1.html\n", rep)
      assert_equal(",0,user@e.com,save,1\n,0,,save,1\n",
		   @site["_SiteChanged"].load)

      rep = @report.make_report(@site)
      assert_equal("09:00 user@e... save http://example.com/test/1.html\n09:00 anonymous save http://example.com/test/1.html\n", rep)

      # @report.send_site(@site)
      # @report.send("hourly")
      @report.send("daily")
      assert_equal(["test@example.com", "user@e.com"], $smtp_sendmail[2..3])
      assert_match(/test@example.com/, $smtp_sendmail[4])
      #puts $smtp_sendmail[4].jistosjis
      str = <<"EOS"
From: test@example.com
To: user@e.com
Subject: http://example.com/test/ レポート
Content-Type: text/plain; charset="ISO-2022-JP"

http://example.com/test/ における、本日の編集記録です。

09:00 user@e... save http://example.com/test/1.html
09:00 anonymous save http://example.com/test/1.html

EOS
      assert_equal(str.sjistojis, $smtp_sendmail[4])

      #list = @report.check_list(@site)
      #qp list

      farm = @memory.farm
      farm.close_all
    end
  end
end
