#!/usr/bin/perl
#
# BNCweb: A user-friendly interface to the British National Corpus - Version 4.3
# Copyright (C) 2005-10 Hoffmann/Evert/Lehmann
#
# Updates and information available at http://www.bncweb.info
#
# This file is part of BNCweb.
# 
# BNCweb is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# 
# BNCweb is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#
# based on BNCweb Version 2.0:
# © 1996/2004 Lehmann/Hoffmann/Schneider
#

use DBI;

use lib "../lib_files";
use bncLibCQPXML;

use Time::HiRes qw (time);

$startTime = time;

$|=1;

# connect to mysql
$bncHandle = DBI->connect("DBI:mysql:$bwMYSQLtable:$bwMYSQLhost:$bwMysqlPort", "$bwMysqlUser", "$bwMysqlPwd") or bark("Can't connect to mysql on $bwMYSQLhost at port: $bwMysqlPort <BR>$userHandle::errstr\n");
$userHandle = DBI->connect("DBI:mysql:$bwMYSQLusertable:$bwMYSQLhost:$bwMysqlPort", "$bwMysqlUser", "$bwMysqlPwd") or bark("Can't connect to mysql on $bwMYSQLhost at port: $bwMysqlPort <BR>$userHandle::errstr\n");
$categorizeHandle = DBI->connect("DBI:mysql:$bwMYSQLcategorizetable:$bwMYSQLhost:$bwMysqlPort", "$bwMysqlUser", "$bwMysqlPwd");

$username = $ENV{'REMOTE_USER'};
$link = '<A HREF="'. $ENV{'HTTP_REFERER'} . '">[Back to BNC Query Result Display]</A>';

unless (getParams($ENV{'QUERY_STRING'})) {
	barkFull("incomplete transmition of URL<BR>This problem is likely to occur in combination with proxy servers<BR>turn off your web-proxy and try again");
}


$qName = $params{qname};

$sqlQuery = "SELECT query, subcorpus FROM savedQueries WHERE theID = '$params{theID}'";
$sth = $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
@rowArray=$sth->fetchrow_array;
$SQquery=$rowArray[0];
$SQsubcorpus=$rowArray[1];
$SQqueryQuote = $bncHandle->quote($SQquery);
$SQsubcorpusQuote = $bncHandle->quote($SQsubcorpus);
$thModeQuote = $bncHandle->quote($params{thMode});
$SQsubcorpusQuote  = '\'\'' unless ($SQsubcorpus);

unless (($SQsubcorpus eq "###") || ($params{aim} eq "categorize")) {
	
	$sqlQuery = "SELECT db_name FROM tableLog WHERE query = $SQqueryQuote and theRestrictions = $SQsubcorpusQuote and thMode = $thModeQuote and db_type = 'distribution' limit 1";
	$sth = $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
	@rowArray=$sth->fetchrow_array;
	$dbname=$rowArray[0];
	
	if ($dbname) {
		$theTime = int(time);
		$sqlQuery = "UPDATE tableLog set crTime = $theTime where db_name='$dbname'";
		$bncHandle->do($sqlQuery) or bark("Can't insert $sqlQuery: " . $bncHandle::errstr);
		setParam("dbname", "$dbname");
	}

}

unless ($dbname) {
	# connect to CQP
	CQPconnect(full);
	
	
	$CQP->exec("set Context 0");			# set context & display options for kwic lines
	$CQP->exec("show -cpos");
	
	
	$dbTime=int(time);
	if ($params{aim} eq "dist") {
		$dbname="${dbTime}_${username}_stat";
	} elsif ($params{aim} eq "categorize") {
		setParam("categorize", "yes");
		setParam("program", "search");
		setParam("dbname", "$params{queryID}");
		$dbname="$params{queryID}";
				
	}
	
	&deleteCachedMySQLTables($bwMaxMySQLSize) if ($params{aim} eq "dist");
	
	# make sure users can't create enormous temp-tables
	$usernameQuote = $bncHandle->quote($username);
	
	$sqlQuery = "select distMax from userLimits where user = $usernameQuote";
	$sth = $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$sth->execute or bark("Can't execute $sqlQuery: ". $sth::errstr);
	@rowArray=$sth->fetchrow_array;
	$distMax=$rowArray[0];
	
	$distMax = $bwDefaultDist if (!$distMax);
	$displayActual = &makeDecimals($params{numOfSolutions});	
	if ($params{numOfSolutions} > $distMax) {
		
		$distMax = &makeDecimals($distMax);
		&printHeader("Disk Space Alert");
		print <<END;
		<P>
		<TABLE BORDER="0" CELLPADDING="3" CELLSPACING="3" WIDTH="100%" BGCOLOR="#FFFFFF">
			<TR>
				<TD WIDTH="100%" HEIGHT="19" BGCOLOR="#CCCCFF"><FONT SIZE="4"><B>Disk Space Alert</B></FONT></TD>
			</TR>
			<TR>
				<TD WIDTH="100%" BGCOLOR="#DDDDDD"><B>The action you have requested would use up too much disk-space!</B></TD>
			</TR>
			<TR>
				<TD WIDTH="100%" BGCOLOR="#DDDDDD">
				
				You were trying to work with $displayActual hits but your limit is currently set to a maximum of $distMax instances.<BR><BR>
				
				You can perform the desired action on a random subset of your data: In the query result display,
				select the option "Thin..." and then enter a number up to the maximum of $distMax. Alternatively, if you really need access to the full set of data, 
				please contact your system administrator who will be able to increase the limit for you.</TD>
			</TR>
		</TABLE>
END
		&printFooter();
		&disconnect();
		exit(0);
	}
	
	
	$decOld="0";
	$oneOld="0";
	
	$CQP->exec("set DataDirectory '/$bwTempPath/'");
	$CQP->exec("$bwCorpus");
	
	($numOfSolutions) = $CQP->exec("size $qName");
		
	$qRes = $qName . "_res";
	
	$CQP->exec("tabulate $qName match text_id, match u_who, match, matchend > '/$bwTempPath/$qRes'");	
	
	$sqlQuery = "DROP TABLE IF EXISTS $dbname";
	
	if ($params{aim} eq "dist") {
		$userHandle->do($sqlQuery);
		$sqlQuery = "CREATE TABLE $dbname (
			fname char(3),
			spid char(20),
			beginPosition int,
			endPosition int,
			refnumber MEDIUMINT AUTO_INCREMENT,
			KEY(spid),
			key(refnumber),
			key(spid),
			key (fname)
			) CHARACTER SET latin1 COLLATE latin1_general_ci";
		$userHandle->do($sqlQuery);
		$sqlQuery = "Alter table $dbname disable keys";
		$userHandle->do($sqlQuery);
		$sqlQuery = "LOAD DATA INFILE '/$bwMySQLTempPath/$qRes' into table $dbname fields escaped by ''";
		$userHandle->do($sqlQuery);
		$sqlQuery = "Alter table $dbname enable keys";
		$userHandle->do($sqlQuery);
		
		$numRows = &getTableSize($dbname);
		
		
	} elsif ($params{aim} eq "categorize") {
		$userHandle->do($sqlQuery);
		
		$default = "";
		$default = "DEFAULT '$params{theDefault}'" ;
		
		$sqlQuery = "CREATE TABLE $dbname (
			fname char(3),
			spid char(20),
			beginPosition int,
			endPosition int,
			refnumber MEDIUMINT AUTO_INCREMENT,
			catName CHAR(50),
			KEY(spid),
			key(refnumber),
			key(spid),
			key (fname),
			key(catName)
			) CHARACTER SET latin1 COLLATE latin1_general_ci";
		$categorizeHandle->do($sqlQuery);

		$sqlQuery = "Alter table $dbname disable keys";
		$categorizeHandle->do($sqlQuery);
		$sqlQuery = "LOAD DATA INFILE '/$bwMySQLTempPath/$qRes' into table $dbname fields escaped by ''";
		$categorizeHandle->do($sqlQuery);
		if ($params{theDefault}) {
			$sqlQuery = "Update $dbname set catName = '$params{theDefault}'";
			$categorizeHandle->do($sqlQuery);
		}
		
		$sqlQuery = "Alter table $dbname enable keys";
		$categorizeHandle->do($sqlQuery);

		$numRows = &getTableSize($dbname);
	
	}
		
	unlink("/$bwTempPath/$qDump") if -f "/$bwTempPath/$qDump";
	unlink("/$bwTempPath/$qRes") if -f "/$bwTempPath/$qRes";
	
	unless ($params{aim} eq "categorize") {
		setParam("dbname", "") ;
		
		$theTime=int(time);
		$sqlQuery = "INSERT INTO tableLog (
				db_name, 
				crTime, 
				thMode,
				query,
				theRestrictions, 
				db_type,
				numRows,
				includeLemma
			) VALUES (
				'$dbname', 
				$theTime,
				$thModeQuote,
				$SQqueryQuote,
				$SQsubcorpusQuote,
				'distribution',
				$numRows,
				''
			)";
		$bncHandle->do($sqlQuery) or bark("Can't insert $sqlQuery: " . $bncHandle::errstr);
	}

	$endTime = time;
	$timeTaken = int((($endTime - $startTime) * 1000) + 0.5)/ 1000;
	setParam("timeTaken","$timeTaken") unless ($params{aim} eq "categorize");

} else {
	setParam("timeTaken","cache") unless ($params{aim} eq "categorize");
}


#setParam("SQL", "");
$theURL = getURLparams();

if ($params{aim} eq "dist") {
	print "Location: /$bwCGIalias/show_distribution.pl?dbname=${dbTime}_${username}_stat&type=INIT&${theURL}&urlTest=yes\n\n";
} elsif ($params{aim} eq "categorize") {
	print "Location: /$bwCGIalias/main.pl?&chunk=1&type=INIT&${theURL}&urlTest=yes\n\n";
}


&CQPdisconnect();
exit (0);

sub htmlHeader {
	# print non-parsed header in order to enable instant printout of hits to browser
	$server_protocol = $ENV{'SERVER_PROTOCOL'};
	$server_software = $ENV{'SERVER_SOFTWARE'};

	print "$server_protocol 200 OK\n";
	print "Server: $server_software\n";
}

