#!/usr/bin/perl
#------------------------------------------------------------------------------
# Report list CGI
#------------------------------------------------------------------------------

use strict;
use utf8;
use CGI;
use HTML::Template;
use TF::CommonUtils;
use TF::SingleLock;
use TF::XMLUtils;
use XML::DOM;

binmode STDOUT, ":utf8";

my $BRAND     = $ENV{'TF_BRANDNAME'} || '';
my $LOCATION  = $ENV{'TF_LOCATION'} || '';
my $USERTYPE  = $ENV{'TF_USERTYPE'} || 'normal';
my $LANGPARAM = TF::CommonUtils::getLangPriority();
my $pagetitle = $ENV{'TF_FOLDER_REPORTSETTINGS'} || '';
my $PAGETITLE = TF::CommonUtils::decodeUTF8($pagetitle);
my $PAGEIMG   = $ENV{'TF_FOLDER_REPORTSETTINGS_IMG'} || '';
my $TF_TOKEN  = $ENV{'TF_TOKEN'} || '';
my $TEMPLATE_FILE = './tmpl/reportsettings.tmpl.' . $LANGPARAM;
my $HOSTNAME      = $ENV{'HTTP_HOST'} || '';
my $SETTINGS_DIR  = $ENV{'TF_CONFIG_ROOT'}."/report" || '/usr/local/teamfile/www/conf/conf.d/report';
my $LOCATION_NAME = $LOCATION;
$LOCATION_NAME    =~ s/\///g;
my $LOCK_FILE     = $SETTINGS_DIR . "/.$LOCATION_NAME.reportsettings.lock";
my $SETTINGS_FILE = $SETTINGS_DIR . "/" . "$LOCATION_NAME" . '.set.xml';
my $SETTINGS_FILE_OLD = $SETTINGS_DIR . "/" . "$HOSTNAME.$LOCATION_NAME" . '.set.xml';

my $TEXT_ja = {
	disk_title => 'ディスク容量レポート',
	disk_desc  => 'ディスク利用状況の定期通知と送信条件',
	open_label => '設定を開く',
	status_on  => '有効',
	status_off => '無効',
};
my $TEXT_en = {
	disk_title => 'Disk Usage Report',
	disk_desc  => 'Scheduled notifications and delivery rules for disk usage',
	open_label => 'Open Settings',
	status_on  => 'Enabled',
	status_off => 'Disabled',
};
my $TEXT = ($LANGPARAM eq 'ja') ? $TEXT_ja : $TEXT_en;

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

main();

sub main {
	my $cgi = CGI->new;
	my $status = '';
	if (!$cgi) {
		TF::CommonUtils::showErrorPage('CGI error', $LANGPARAM);
		return;
	}

	my $cmd = $cgi->param('hidCmd') || '';
	if ($cmd eq 'toggle_disk') {
		if (($cgi->request_method || '') ne 'POST' || !$TF_TOKEN ||
			(($cgi->param('hidcsrftoken') || '') ne $TF_TOKEN)) {
			TF::CommonUtils::showErrorPage(
				($LANGPARAM eq 'ja') ? '不正なリクエストです' : 'Invalid request.',
				$LANGPARAM
			);
			return;
		}

		my $lock = TF::SingleLock->new($LOCK_FILE);
		if (!$lock->waitForLocking(5)) {
			$status = ($LANGPARAM eq 'ja') ? 'サーバがビジーです。しばらく経ってからやり直してください' : 'The server is busy. Please retry this operation after a while.';
		}
		else {
			my %params = readDiskSettingsFile($SETTINGS_FILE);
			my $func = $cgi->param('func') || 'off';
			$params{active} = ($func eq 'on') ? 1 : 0;
			storeDiskSettingsFile($SETTINGS_FILE, \%params);
			$lock->release();
		}
	}

	my %params = readDiskSettingsFile($SETTINGS_FILE);
	my $active = $params{active} ? 1 : 0;

	if (!open(TEMPLATE, "<", $TEMPLATE_FILE)) {
		TF::CommonUtils::showTemplateOpenErr($LANGPARAM);
		return;
	}

	binmode TEMPLATE, ":utf8";
	my $htmltmpl = HTML::Template->new(
		filehandle => *TEMPLATE,
		case_sensitive => 1,
		die_on_bad_params => 0
	);

	if (!$htmltmpl) {
		close TEMPLATE;
		TF::CommonUtils::showErrorPage('Template error', $LANGPARAM);
		return;
	}

	$htmltmpl->param(
		brandname  => $BRAND,
		pagetitle  => $PAGETITLE,
		pageimg    => $PAGEIMG,
		status     => $status,
		disk_title => $TEXT->{disk_title},
		disk_desc  => $TEXT->{disk_desc},
		open_label => $TEXT->{open_label},
		disk_checked => $active ? 'checked' : '',
		disk_active_text => $active ? $TEXT->{status_on} : $TEXT->{status_off},
		disk_uri   => $LOCATION . '/.cgi-bin/reportdisksettings',
		token      => $TF_TOKEN,
	);

	print $cgi->header(-charset => 'utf-8');
	print $htmltmpl->output;
	close TEMPLATE;
}

sub readDiskSettingsFile {
	my $filepath = shift || '';
	my %params = (
		active => 0,
		hour   => '',
		min    => '',
		from   => '',
		to     => '',
		hostname => '',
		location => '',
		subject  => '',
		phsubject => '',
		datetimefmt => 'default',
		trigger => '',
		stg_limit => '',
		stg_limit_per => '',
	);

	if (-f $SETTINGS_FILE_OLD) {
		rename($SETTINGS_FILE_OLD, $SETTINGS_FILE);
	}
	return %params if (!$filepath || !-f $filepath);

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

	for my $elem ($doc->getElementsByTagName("state")) {
		my $nodelist = $elem->getElementsByTagName("active");
		$params{active} = ($nodelist && $nodelist->getLength > 0) ? 1 : 0;
	}

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

	for my $elem ($doc->getElementsByTagName("reportsetting")) {
		$params{from} = TF::XMLUtils::getText($elem, "from");
		$params{to} = TF::XMLUtils::getText($elem, "to");
		$params{hostname} = TF::XMLUtils::getText($elem, "hostname");
		$params{location} = TF::XMLUtils::getText($elem, "location");
		$params{subject} = TF::XMLUtils::getText($elem, "subject");
		$params{phsubject} = TF::XMLUtils::getText($elem, "phsubject");
		$params{datetimefmt} = TF::XMLUtils::getText($elem, "datetimefmt");
		$params{trigger} = TF::XMLUtils::getText($elem, "trigger");
		$params{stg_limit} = TF::XMLUtils::getText($elem, "stg-limit");
		$params{stg_limit_per} = TF::XMLUtils::getText($elem, "stg-limit-per");
	}

	$doc->dispose;
	return %params;
}

sub storeDiskSettingsFile {
	my $filepath = shift || '';
	my $params_ref = shift || undef;
	return if (!$filepath || !$params_ref);

	my %params = %{$params_ref};
	my $hour = sprintf("%02d", ($params{hour} ne '' ? $params{hour} : 0));
	my $min  = sprintf("%02d", ($params{min} ne '' ? $params{min} : 0));

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

	my $edit = $doc->createElement("reportsetting");
	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);

	my $mail = $doc->createElement("mail");
	TF::XMLUtils::appendTextElement($doc, $mail, "from", $params{from});
	TF::XMLUtils::appendTextElement($doc, $mail, "to", $params{to});
	$edit->appendChild($mail);

	TF::XMLUtils::appendTextElement($doc, $edit, "hostname", $params{hostname});
	TF::XMLUtils::appendTextElement($doc, $edit, "location", $params{location});
	TF::XMLUtils::appendTextElement($doc, $edit, "subject", $params{subject});
	TF::XMLUtils::appendTextElement($doc, $edit, "phsubject", $params{phsubject});
	TF::XMLUtils::appendTextElement($doc, $edit, "datetimefmt", $params{datetimefmt});
	TF::XMLUtils::appendTextElement($doc, $edit, "trigger", $params{trigger});
	TF::XMLUtils::appendTextElement($doc, $edit, "stg-limit", $params{stg_limit});
	TF::XMLUtils::appendTextElement($doc, $edit, "stg-limit-per", $params{stg_limit_per});
	$doc->appendChild($edit);
	$doc->printToFile($filepath);
	$doc->dispose;
}
