#!/usr/bin/perl
#------------------------------------------------------------------------------
# $Id$
#------------------------------------------------------------------------------
# AutoDelete batch setting CGI
#
# Copyright (c) BAYBITS LLC. All rights reserved.
#------------------------------------------------------------------------------

use strict;
use utf8;
use HTTP::Request::Common qw(POST);
use XML::DOM;
use URI::Escape;
use CGI;
use HTML::Template;
use TF::XMLUtils;
use TF::SingleLock;
use TF::CommonUtils;
use Encode;

binmode STDOUT, ":utf8";	# 標準出力はUTF8

#
# global
#
my $BRAND         = $ENV{'TF_BRANDNAME'} || '';
my $USERID        = $ENV{'REMOTE_USER'} || '';
my $PASSWD        = $ENV{'TF_USERPLAINPASSWORD'} || '';
my $LOCATION      = $ENV{'TF_LOCATION'} || '';
my $PATH_INFO     = $ENV{'PATH_INFO'} || '';
my $USERTYPE      = $ENV{'TF_USERTYPE'} || 'normal';
my $LANGPARAM     = TF::CommonUtils::getLangPriority();

my $TF_AUTODELETE = $ENV{'TF_AUTODELETE'} || 'off';
my $SETTINGS_DIR  = $ENV{'TF_AUTODELETE_CONFIG_ROOT'} || '/usr/local/teamfile/www/conf/conf.d/autodelete';
my $LOCATION_NAME = $LOCATION;
$LOCATION_NAME    =~ s/\///g;
my $LOCK_FILE     = $SETTINGS_DIR . "/.$LOCATION_NAME.editbat.lock";
my $pagetitle     = $ENV{'TF_FOLDER_AUTODELETE'} || '';
my $PAGETITLE     = TF::CommonUtils::decodeUTF8($pagetitle);
my $PAGEIMG       = $ENV{'TF_FOLDER_AUTODELETE_IMG'} || '';

# (note) このパスは、tfscheduler スクリプトも意識しています. 修正するなら両方直しなさい
my $SETTINGS_FILE = $SETTINGS_DIR . $LOCATION . '.set.xml';
my $SETTINGS_FILE_BAK = $SETTINGS_FILE . '.bak';
my $TEMPLATE_FILE = './tmpl/editbat.tmpl.' . $LANGPARAM;
my $BACKURI       = $LOCATION . "/.cgi-bin/autodelsetting";

my $ERRORTABLE_ja = {
					CGIError => "CGIエラーです",
					templateError => "テンプレートオブジェクトが生成できません",
					readTemplateError => "テンプレートファイルの読み込みに失敗しました",
					serverBusy => "サーバがビジーです。しばらく経ってからやり直してください",
					paramError => "正常な値を入力してください",
					nothing => "入力していない箇所があります",
					nodays => "日数に０は指定できません",
				};

my $ERRORTABLE_en = {
					CGIError => "CGI error found.",
					templateError => "Can not create template object.",
					readTemplateError => "Failed to read template file.",
					serverBusy => "The server is busy. Please retry this operation after a while.",
					paramError => "Please specify normal value.",
					nothing => "Please input all parameter.",
					nodays => "Can not input 0 to days.",
				};

my $ERRORTABLE = ($LANGPARAM eq 'ja') ? $ERRORTABLE_ja : $ERRORTABLE_en;

if (!$LOCATION || !$USERTYPE || ($USERTYPE ne 'admin' && $USERTYPE ne 'groupleader') || $TF_AUTODELETE ne 'on') {
	TF::CommonUtils::showAccessDeny();
	die '';
}

main();

#
#	メインルーチン
#
sub main {
	my $status = '';
	my $isActive = 0;
	my $hour;
	my $min;
	my $period;
	my $cgi = new CGI;
	if( ! $cgi ) {
		TF::CommonUtils::showErrorPage($ERRORTABLE->{CGIError}, $LANGPARAM);
		print STDERR "CGI Object error";
		return;
	}

	if( $cgi->cgi_error ) {
		TF::CommonUtils::showErrorPage($ERRORTABLE->{CGIError} . '(' . $cgi->cgi_error . ')', $LANGPARAM);
		print STDERR "CGI Error (" . $cgi->cgi->error . ")";
		return;
	}

	my $cmd  = $cgi->param('hidCmd') || '';

	#
	# 排他処理
	#
	my $lock = TF::SingleLock->new($LOCK_FILE);
	if( ! $lock->waitForLocking(5) ) {
		showResponse( $cgi, $ERRORTABLE->{serverBusy}, '', undef);
		$lock->release();
		die "Server busy ($$)";
	}

	# 更新時
	if ($cmd eq 'set') {

		# 現在の設定値を読み込む
		my %read_params = readSettingsFile($SETTINGS_FILE);

		my $enc_hour   = $cgi->param('hour');
	    my $enc_min    = $cgi->param('min');
	    my $enc_period = $cgi->param('days');

		$hour   = TF::CommonUtils::decodeUTF8($enc_hour);
		$min    = TF::CommonUtils::decodeUTF8($enc_min);
		$period = TF::CommonUtils::decodeUTF8($enc_period);

		my $actv = $cgi->param('func') || 'off';
		$isActive = ($actv eq 'on') ? 1 : 0;

		# POSTデータを反映する
		$read_params{active} = $isActive;
		$read_params{hour}   = $hour;
		$read_params{min}    = $min;
		$read_params{period} = $period;

		#空欄がある場合はエラー
		if($hour eq '' || $min eq '' || $period eq '') {
			$status = $status . $ERRORTABLE->{nothing} . '<br/>';

			$lock->release();
			showResponse($cgi, $status, '', \%read_params);
			return;
		}

		#
		#時、分、日の連結。if文を見やすくするため
		#
		my $check = $hour . $min . $period;

		#
		#範囲外の値はエラー
		#
		if ( $check =~ /^[0-9]*[0-9]$/) {
			if ( !($hour >= 0 && $hour <= 23) || !($min >= 0 && $min <= 59) || !($period >= 1) ) {
				if ($period == 0) {
					$status = $status . $ERRORTABLE->{nodays} . '<br/>';
				}
				else {
					$status = $status . $ERRORTABLE->{paramError} . '<br/>';
				}
				$lock->release();
				showResponse($cgi, $status, '', \%read_params);
				return;
			}
		}
		else {
			$status = $status . $ERRORTABLE->{paramError} . '<br/>';
			$lock->release();
			showResponse($cgi, $status, '', \%read_params);
			return;
		}

		# バックアップ
	    unlink $SETTINGS_FILE_BAK;
	    rename $SETTINGS_FILE,$SETTINGS_FILE_BAK;

		# ファイルに出力する
		storeSettingsFile($SETTINGS_FILE, \%read_params);
	}

	# 設定ファイルの読み出し
	my %params = readSettingsFile($SETTINGS_FILE);

	$lock->release();
	showResponse($cgi, $status, $cmd, \%params);
}

#
# レスポンスの出力
#
sub showResponse {
	my %emptyhash = ();
	my $succeeded = 0;
	my $cgi       = shift || undef;
	my $status    = shift || '';
	my $cmd       = shift || '';
	my $params_ref= shift || \%emptyhash;

	my %params    = %{$params_ref};
	my $action1;
	my $action2;

	if ($cmd eq 'set') {
		TF::CommonUtils::redirectPage($BACKURI, $LANGPARAM);
		return;
	}

	if ($params{active}) {
        $action1 = "checked";
        $action2 = "";
    }
	else {
        $action1 = "";
        $action2 = "checked";
    }

	if( $cgi ) {
		if( open TEMPLATE, "<", $TEMPLATE_FILE ) {
			binmode TEMPLATE, ":utf8";					# テンプレートファイルはUTF8扱いで読み込む	
			my $htmltmpl = HTML::Template->new( filehandle => *TEMPLATE,
												case_sensitive => 1,
												die_on_bad_params => 0);
			#パラメータの受け渡し
			if( $htmltmpl ) {
				$htmltmpl->param(	hour => $params{hour},
									min  => $params{min},
									day  => $params{period},
									chk1 => $action1,
									chk2 => $action2,
									status => $status,
									brandname => $BRAND,
									pagetitle => $PAGETITLE,
									pageimg   => $PAGEIMG,
									isWritable => ($USERTYPE eq 'admin') ? 1 : 0,
								);
				
				print $cgi->header( -charset => 'utf-8' );
				print $htmltmpl->output;
				$succeeded = 1;
			}
			else {
				$status = $status . $ERRORTABLE->{templateError} . '<br/>';
			}
			close TEMPLATE;
		}
		else {
			$status = $status . $ERRORTABLE->{readTemplateError} . '<br/>';
		}
	}
	else {
		$status = $status . $ERRORTABLE->{CGIError} . '<br/>';
	}

	if( ! $succeeded ) {
		TF::CommonUtils::showErrorPage($status, $LANGPARAM);
		return;
	}
}

#
# Read settings file
#
sub readSettingsFile {
	my $filepath   = shift || '';

	if (!$filepath) {
		return;
	}

	my $isActive = 0;
	my $hour     = '';
	my $min      = '';
	my $period   = '';

	if (-f $filepath) {
		my $xml = new XML::DOM::Parser;
		my $doc = $xml->parsefile($filepath);

		for my $elem ( $doc->getElementsByTagName("state") ) {
			my $nodelist = $elem->getElementsByTagName("active");
			if ($nodelist && $nodelist->getLength > 0) {
				$isActive = 1;
			}
			else {
				$isActive = 0;
			}
		}

		for my $elem ( $doc->getElementsByTagName("starttime") ) {
			$hour = TF::XMLUtils::getText($elem,"hour");
			$min  = TF::XMLUtils::getText($elem,"minutes");
		}

		for my $elem ( $doc->getElementsByTagName("autodeletesetting") ) {
			$period = TF::XMLUtils::getText($elem,"logdeleteperiod");
		}
		$doc->dispose;
	}

	my %params =	(	active => $isActive,
						hour   => $hour,
						min    => $min,
						period => $period,
					);
	return %params;
}

#
# Store data to settings file
#
sub storeSettingsFile {
	my $filepath   = shift || '';
	my $params_ref = shift || undef;

	if (!$filepath || !$params_ref) {
		return;
	}

	# 前ゼロ　　0時0分がファイルに書き込めないため
	my %params = %{$params_ref};
	my $hour = sprintf("%02d",$params{hour});
	my $min  = sprintf("%02d",$params{min});

	my $doc = new XML::DOM::Document;
    my $pi_decl = $doc->createXMLDecl('1.0','utf-8','yes');

	$doc->setXMLDecl($pi_decl);

	my $edit = $doc->createElement("autodeletesetting");
	my $editstate = $doc->createElement("state");

	if ($params{active}) {
		my $e = $doc->createElement("active");
		$editstate->appendChild($e);
	}
	else {
		my $e = $doc->createElement("inactive");
		$editstate->appendChild($e);
	}
	$edit->appendChild($editstate);

	my $editstime = $doc->createElement("starttime");

	TF::XMLUtils::appendTextElement($doc, $editstime, "hour",    $hour);
	TF::XMLUtils::appendTextElement($doc, $editstime, "minutes", $min);
	$edit->appendChild($editstime);

	TF::XMLUtils::appendTextElement($doc, $edit, "logdeleteperiod", $params{period} + 0);
	$doc ->appendChild($edit);

	$doc ->printToFile($filepath);
	$doc ->dispose;
}

