package TDS::Static;
# $Id: Static.pm,v 1.27 2001/01/10 08:12:44 tom Exp $
################################################################
##warn times, " static";

=head1 NAME

TDS::Static - static mode

=head1 SYNOPSIS

 use TDS::Static;

 $s = new TDS::Static;
 $s->UpdateRecent;
 $s->UpdateMonth(1999, 10);

=cut    

################################################################

use strict;

use File::Copy;

use vars qw(@ISA $TMP
	    $HtmlDir $HtmlSuffix $RecentHtml %AllowedActions);
@ISA = qw(ObjectTemplate);

use ObjectTemplate;
use CGI::QueryString;
use FileSpec;

use TDS;
use TDS::System;
use TDS::Status;
use TDS::Renderer;
use TDS::Collection;
use TDS::Summary;
use TDS::List::Url;
use TDS::List::Dictionary;
use TDS::Cache;
use TDS::DirInfo;
use TDS::Di;
use TDS::LastModified;

$TMP = $ENV{'TMP'} || $ENV{'TEMP'} || '.';
$HtmlDir = "." unless defined $HtmlDir;
$HtmlSuffix = "html" unless defined $HtmlSuffix;
$RecentHtml = "index.html" unless defined $RecentHtml;

%AllowedActions = ('recent'=>1, 'month'=>1, 'summary'=>1,
		   'url'=>1, 'dictionary'=>1, 'hina_di'=>1,
		   'sigsearch'=>1, 'get'=>1
		   );

attributes qw(last_modified only_this_month
	      actions stock_message
	      quiet force);

################################################################

=head1 MEMBER FUNCTIONS

=cut

sub initialize($)
{
    my $self = shift;

    $self->actions({});

    $self->SUPER::initialize;
}

sub AddAction($$)
{
    my ($self, $action) = @_;

    die unless $AllowedActions{$action};
    $self->actions->{$action} = 1;
}

sub AddAllAction($)
{
    my $self = shift;
    
    for (keys %AllowedActions){
	$self->actions->{$_} = 1;
    }
}

sub Do ($)
{
    my $self = shift;

    my $start_time = time();

    # update lastmodified
    $TDS::Status->lmo->GetRealLastModified;
    
    my $updated;

    $self->message("start\n");
    # current(digest)
    $updated = $self->UpdateRecent
	if $self->actions->{"recent"};

    # monthly, partly
    $self->UpdateMonthly($self->only_this_month)
	if $self->actions->{"month"};

    # expire cache
    if ($TDS::Cache::EnableCache && $self->actions->{month}){
	$self->message("cache expire...");
	use TDS::Cache::Expire;
	my $exp = new TDS::Cache::Expire(quiet=>1);
	$exp->Do("expire");
	$self->message("done\n");
    }
    
    # summary
    $self->UpdateSummary
	if $self->actions->{"summary"};

    # URL
    $self->UpdateUrl
	if $self->actions->{"url"};

    # dictionary
    $self->UpdateDictionary
	if $self->actions->{"dictionary"};

    # hina.di
    if (# $TDS::System::Output_hina_di &&
	($self->actions->{"hina_di"} || $updated)){
	$self->message("update hina.di\n");
	my $di = new TDS::Di(no_expire=>1,
			     filename=>GetHtmlDir() ."/hina.di");
	$di->Write($self->last_modified);
    }
    # signature files for search
    if ($TDS::Search::UseSignatureMethod && $self->actions->{"sigsearch"}){
	$self->message("update signature files\n");
	my $search = new TDS::Search;
	$search->UpdateSignatureFiles(1);    # only this month
    }
    # done
    
    my $elasp_time = time() -$start_time;
    $self->message("elasped: $elasp_time\n");

    $self->DoneHook;
}

sub UpdateRecent
{
    my $self = shift;

    my $recent_file = GetHtmlDir() . "/$RecentHtml";

#    die $recent_file;
    $TDS::Status->mode('RECENT');
    my $rend = new TDS::Renderer;
    $self->message("recent($recent_file):");
    $rend->Read;
    my $col = new TDS::Collection;
    my $lm;
    
    if ($self->force){
	$lm = 0;
    } else {
	$lm = (stat($recent_file))[9];
    }
    $self->last_modified($lm);
    
    my $updated;
    if ($col->Read($lm) == 0){
	$self->message("[S]");
    } else {
	$updated = 1;
	$self->message("[U]");
	my $tmp_file = "$TMP/.tds-recent-$$";
	open(F, ">$tmp_file") || die;
	print F $rend->AsHTML($col);
	close F;
	move($tmp_file, $recent_file);
    }
    $self->message("\n");
    return $updated;
}

sub UpdateMonthly($;$)
{
    my ($self, $only_this) = @_;

    $TDS::Status->mode("MONTH");
    my $col = new TDS::Collection;
    $self->message("monthly...\n");
    my $now_year = $TDS::Status->start_time->year;
    my $start_month = $TDS::Status->start_time->month;

#    $start_month = 10;     # debug

    my $is_exist; 
    # search in incresing order
    for (reverse ($TDS::Status->start_year..$now_year)){
	my $year = $_;
	$TDS::Status->year($year);
	my $i;
	# for each year
	for ($i=$start_month; $i>=1; $i--){
	    my $month = sprintf("%02d", $i);
	    my $mark;
	    $self->message("$year/$month:[");
	    if ($TDS::Collection::AllowAllMonthly){
		# all month
		$mark = $self->update_the_month($year, $month, undef, $col);
		$self->message("$mark:");
		$is_exist ||= $mark ne '-';
		
		# skip if no diary exists
		if ($mark eq '-'){
		    $self->message("]\n");
		    next;
		}
	    }
	    # partly
	    for (qw(a b c)){
		my $part = $_;
		$mark = $self->update_the_month($year, $month, $part, $col);
		$self->message("$mark,");
		$is_exist ||= $mark ne '-';
	    }
	    $self->message("]\n");
	    # in only this month: if this month not exists, search until any diary exists
	    if ($is_exist && $only_this){
		return;
	    }
	}
	$start_month = 12;    # starting with Dec in second loop
    }
}

sub UpdateSummary
{
    my $self = shift;

    $self->message("summary...");

    my $summary = new TDS::Summary;
    $summary->Read;

    my $tmp_file = "$TMP/.tds-summary-$$";
    open(F, ">$tmp_file") || die;
    print F $summary->AsHTML;
    close F;
    move($tmp_file, GetHtmlDir() . "/summary.html");
    $self->message("done.\n");
}
sub UpdateUrl
{
    my $self = shift;
    
    $self->message("url...");
    my $src_lm = (stat(GetDataDir() . "/url.dat"))[9];
    my $dst_lm = (stat(GetHtmlDir() . "/url.html"))[9];

    if ($self->force || $src_lm > $dst_lm){
	my $url = new TDS::List::Url;
	$url->Read;
	my $tmp_file = "$TMP/.tds-url-$$";
	open(F, ">$tmp_file") || die;
	print F $url->AsHTML;
	close F;
	move($tmp_file, GetHtmlDir() . "/url.html");
	$self->message("updated.\n");
    } else {
	$self->message("skipped.\n");
    }
}
sub UpdateDictionary
{
    my $self = shift;

    $self->message("dictionary...");

    my $src_lm = (stat(GetDataDir() . '/dictionary.dat'))[9];
    my $dst_lm = (stat(GetHtmlDir() . "dictionary.html"))[9];
    
    if ($self->force || $src_lm > $dst_lm){
	my $dictionary = new TDS::List::Dictionary;
	$dictionary->Read;
	my $tmp_file = "$TMP/.tds-dictionary-$$";
	open(F, ">$tmp_file") || die;
	print F $dictionary->AsHTML;
	close F;
	move($tmp_file, GetHtmlDir() . "/dictionary.html");
	$self->message("updated.\n");
    } else {
	$self->message("skipped.\n");
    }
}
    
################################################################

=head2 $s->update_the_month($year, $month, $part, $col);

update specified diarys of month or part.
return
    'U': updated
    'S': skipped
    '-': not exists

=cut

sub update_the_month($$$$$$)
{
    my ($self, $year, $month, $part, $col) = @_;

    
    $col->ClearDiarys;
    
#    my $col = new TDS::Collection;
    
#    param('keywords', "$year$month$part");
    $TDS::Status->month($month);
    $TDS::Status->day_part($part);

    my $tmp_file = "$TMP/.tds-$year$month$part-$$";
    my $filename = GetHtmlDir() . "/d$year$month$part.$HtmlSuffix";
    my $lm = ($self->force) ? 0 : (stat($filename))[9];

#    my $num = $col->Read(new TDS::Status, $lm);
    my $num = $col->Read($lm);
    return  "-" if $num < 0;    # no diary exists

#    print "output lm: $lm\n";
    
    if ($num == 0){  # not updated
	return 'S';
    } else {
	my $rend = new TDS::Renderer;
	$rend->Read;
#	open(F, ">$filename") || die $filename;
	open(F, ">$tmp_file") || die $tmp_file;
	print F $rend->AsHTML($col);
	close F;
	move($tmp_file, $filename);
	return 'U';
    }
}
sub message ($$)
{
    my ($self, $message) = @_;

    print $message unless $self->quiet;
    $self->stock_message($self->stock_message . $message);
}

sub DoneHook{}

sub GetHtmlDir
{
    return FileSpec->rel2abs($HtmlDir, GetWebDiaryDir());
}
1;
