#!/usr/bin/perl
#------------------------------------------------------------------------------
# $Id$
#------------------------------------------------------------------------------
# Show deleted file list
#
# Copyright (c) BAYBITS LLC. All rights reserved.
#------------------------------------------------------------------------------

use strict;
use utf8;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use XML::DOM;
use URI::Escape;
use CGI;
use HTML::Template;
use TF::XMLUtils;
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 ($SCHEMA,$SERVER_PORT,$URI_PREFIX) = TF::CommonUtils::getCgiConnectInfo();
my $URL           = $URI_PREFIX . $LOCATION;
my $TF_AUTODELETE = $ENV{'TF_AUTODELETE'} || 'off';
my $SETTINGS_DIR  = $ENV{'TF_AUTODELETE_CONFIG_ROOT'} || '/usr/local/teamfile/www/conf/conf.d/autodelete';
my $pagetitle     = $ENV{'TF_FOLDER_AUTODELETE'} || '';
my $PAGETITLE     = TF::CommonUtils::decodeUTF8($pagetitle);
my $PAGEIMG       = $ENV{'TF_FOLDER_AUTODELETE_IMG'} || '';

my $EXTMAP_FILE     = $ENV{'TF_EXTMAP_PATH'} || '';
my $EXTMAP_DEF_FILE = $ENV{'TF_DEFAULT_EXTMAP_PATH'} || '';

my $TEMPLATE_FILE = './tmpl/autodelhistory.tmpl.' . $LANGPARAM;

my $ERRORTABLE_ja = {
					CGIError => "CGIエラーです",
					templateError => "テンプレートオブジェクトが生成できません",
					readTemplateError => "テンプレートファイルの読み込みに失敗しました",
				};

my $ERRORTABLE_en = {
					CGIError => "CGI error found.",
					templateError => "Can not create template object.",
					readTemplateError => "Failed to read template file.",
				};

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

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

#
# main
#
sub main {
	my @paramarray = ();

	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 $srctype  = $cgi->param('srctype') || '';	# 'admin' or ''
	my $pgid     = $cgi->param('pgid') || '';
	my $gid      = $cgi->param('cgroupid') || '';

	if ($srctype ne 'admin') {
		$gid = TF::CommonUtils::decipherNumericValue($gid);
	}

	# 一般ユーザの場合、グループフォルダ画面経由のアクセスでは
	# $gid のグループにアクセスできるかどうかチェックする
	if (!$srctype && $USERTYPE ne 'admin') {
		if (validateGroupFolderAccess($gid)) {
			TF::CommonUtils::showAccessDeny();
			return;
		}
	}

	# 対象グループが存在していてアクティブかどうか判定する

	my $fdeleted = $SETTINGS_DIR . $LOCATION . '.del.' . $gid . '.xml';

	# read XML file
	readAutoDeletedList($fdeleted, \@paramarray);

	my $backurl = undef;
	if ($srctype eq 'admin') {
		$backurl = $LOCATION . "/.cgi-bin/autodelsetting?hidCmd=list&cgroupid=$pgid";
	}
	else {
		$backurl = $ENV{'TF_GROUPFOLDER_URI'} || $LOCATION;
		$backurl = $backurl . '?WEBDAV_METHOD=PROPFIND';
	}

	# show response
	showResponse($cgi, $backurl, \@paramarray);
}

#
# Show response
#
sub showResponse {
    my @emptyarray = ();

	my $cgi            = shift || undef;
	my $backurl        = shift || '';
    my $paramarray_ref = shift || \@emptyarray;

	my $status         = '';
	my $succeeded = 0;

	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(	backurl   => $backurl,
									brandname => $BRAND,
									pagetitle => $PAGETITLE,
									pageimg   => $PAGEIMG,
									fileloop  => $paramarray_ref,
								);
				
				print $cgi->header( -charset => 'utf-8' );
				print $htmltmpl->output;
				$succeeded = 1;
			}
			else {
				$status = $ERRORTABLE->{templateError} . '<br/>';
			}
			close TEMPLATE;
		}
		else {
			$status = $ERRORTABLE->{readTemplateError} . '<br/>';
		}
	}
	else {
		$status = $ERRORTABLE->{CGIError} . '<br/>';
	}

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

#
# read deleted list file
#
sub readAutoDeletedList {
	my $filepath  = shift || '';
	my $param_ref = shift || undef;

	if (! -f $filepath || !$param_ref) {
		return;
	}

	my (%type_maps, %ext_maps) = readExtMap();
	my $elemcount = 0;

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

	for my $elem ($doc->getElementsByTagName("filelist")) {
		my $displayname      = TF::XMLUtils::getText($elem, "displayname");

		my $getcontentlength = TF::XMLUtils::getText($elem, "getcontentlength");
		my $getcontentlength_str = byte2displaysize($getcontentlength);
		my $getcontenttype   = TF::XMLUtils::getText($elem, "getcontenttype");
		my $lastmodifier     = TF::XMLUtils::getText($elem, "lastmodifier");

		my ($dispcontenttype, $summaryicon) = applyExtmap(\%type_maps, \%ext_maps, $displayname, $getcontenttype);
		if (!$summaryicon) {
			$summaryicon = "/icons/teamfile/tf_unknown.gif";
		}

		my $getlastmodified  = TF::XMLUtils::getText($elem, "getlastmodified");
		my $getlastmodified_str = epoch2datestr($getlastmodified);

		my $deletion = TF::XMLUtils::getText($elem, "deletion");
		my $deletion_str = epoch2datestr($deletion);

		push (@{$param_ref},
						{	displayname      => $displayname,
							getcontentlength => $getcontentlength_str,
							getcontenttype   => $dispcontenttype,
							lastmodifier     => $lastmodifier,
							getlastmodified  => $getlastmodified_str,
							deletion         => $deletion_str,
							summaryicon      => $summaryicon,
							elemcount        => $elemcount++,
						}
				);
	}
	$doc->dispose;
}

#
# Validation of group-folder access
#
sub validateGroupFolderAccess {
	my $groupid = shift || '';

	if (!$groupid) {
		return 1;
	}

	# Request "userinformationsearch (availablegroup)"

	my $ua  = LWP::UserAgent->new(ssl_opts => {verify_hostname => 0});
	my $req = HTTP::Request->new;

	$req->uri($URL . "/.management/USER/");
	$req->method("SEARCH");
	$req->protocol("HTTP/1.1");
	$req->authorization_basic($USERID, $PASSWD);
	$req->content("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><D:searchrequest xmlns:D=\"DAV:\" xmlns:TF=\"http://www.teamfile.com/DTD/TF/\"><TF:userinformationsearch><TF:userid>$USERID</TF:userid><TF:availablegroup/></TF:userinformationsearch></D:searchrequest>");
	$ua->agent(TF::CommonUtils::getCgiUserAgent());

	my $res = $ua->request($req);

	if ( $res->is_success ) {
		my $data = $res->content();
		# parse response XML
		my $xml = new XML::DOM::Parser;
		my $doc = $xml->parse($data);
		my $res_groupid;
		my $state;
		my $isActive = 0;

		for my $elem ( $doc->getElementsByTagName("TF:groupinfo") )  {
			$isActive = 1;

			$res_groupid = TF::XMLUtils::getText($elem, "TF:groupid");
			$state = $elem->getElementsByTagName("TF:state");
			if ($state) {
				my $active = $state->item(0);
				if ( $active ) {
					for my $node ($active->getChildNodes) {

						if ($node->getNodeName eq "TF:inactive") {
							$isActive = 0;
						}
					}
				}
			}

			if ($res_groupid && $res_groupid eq $groupid && $isActive) {
				$doc->dispose;
				return 0;
			}
		}
		$doc->dispose;
	}

	return 1;
}

#
# Read extmap files
#
sub readExtMap {
	my %type_maps = ();
	my %ext_maps  = ();

	if (!$EXTMAP_FILE || !$EXTMAP_DEF_FILE) {
		return (%type_maps, %ext_maps);
	}

	# デフォルト拡張子マップを読む
	if (-f $EXTMAP_DEF_FILE && open F_EXTMAP, "<", $EXTMAP_DEF_FILE) {
		while (<F_EXTMAP>) {
			if ($_ =~ /^[ \t]*#/) {
				next;
			}
			my $line = $_;
			$line =~ s/\n//g;

			my ($type, $ext, $imgpath, $name) = split(/,/, $line);
			my $dec_name = TF::CommonUtils::decodeUTF8($name);

			if ($type && $type ne '-') {
				$type_maps{$type} = {	type => $type,
										ext => ($ext ne '-' ? $ext : ''),
										imgpath => $imgpath,
										name => $dec_name,
									};
			}

			if ($ext && $ext ne '-') {
				$ext_maps{$ext} = {		type => $type,
										ext => ($ext ne '-' ? $ext : ''),
										imgpath => $imgpath,
										name => $dec_name,
									};
			}

		}
		close F_EXTMAP;
	}

	# 拡張子マップを読む
	if (-f $EXTMAP_FILE && open F_EXTMAP, "<", $EXTMAP_FILE) {
		while (<F_EXTMAP>) {
			if ($_ =~ /^[ \t]*#/) {
				next;
			}
			my $line = $_;
			$line =~ s/\n//g;

			my ($type, $ext, $imgpath, $name) = split(/,/, $line);
			my $dec_name = TF::CommonUtils::decodeUTF8($name);

			if ($type && $type ne '-') {
				$type_maps{$type} = {	type => $type,
										ext => ($ext ne '-' ? $ext : ''),
										imgpath => $imgpath,
										name => $dec_name,
									};
			}

			if ($ext && $ext ne '-') {
				$ext_maps{$ext} = {		type => $type,
										ext => ($ext ne '-' ? $ext : ''),
										imgpath => $imgpath,
										name => $dec_name,
									};
			}
		}
		close F_EXTMAP;
	}

	return (%type_maps, %ext_maps);
}

#
sub applyExtmap {
	my $type_maps_ref = shift || undef;
	my $ext_maps_ref  = shift || undef;
	my $name          = shift || undef;
	my $type          = shift || undef;

	my $disptype = undef;
	my $imgpath  = undef;

	if ($type_maps_ref && $type) {
		my %type_maps = %{$type_maps_ref};

		my $tmpname = $type_maps{$type}->{name};
		$disptype = TF::CommonUtils::decodeUTF8($tmpname);
		$imgpath  = $type_maps{$type}->{imgpath};
	}

	if (!$disptype && $ext_maps_ref && $name) {
		my ($prefix, $ext) = split(/./, $name);
		my %ext_maps = %{$ext_maps_ref};

		my $tmpname = $ext_maps{$ext}->{name};
		$disptype = TF::CommonUtils::decodeUTF8($tmpname);
		$imgpath  = $ext_maps{$ext}->{imgpath};
	}

	return ($disptype, $imgpath);
}

#
sub byte2displaysize {
	my $size = shift || '';
	my $ssize = '';

	if (!$size) {
		return '0 KB';
	}

	if ($size < 1024) {
		if ($size == 0) {
			$ssize = '0 KB';
		}
		else {
			$ssize = '1 KB';
		}
	}
	else {
		$ssize = int($size / 1024) . ' KB';
	}

	return $ssize;
}

#
sub epoch2datestr {
	my $misec = shift || 0;
	if ($misec == 0) {
		return '';
	}

	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($misec / 1000000);
	return sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec);
}

