#!/usr/bin/perl
use strict;
use warnings;

package API::Cart;

our $Config;
BEGIN{
	use API::Config;
	$Config = $API::Config::Config;
}
use lib ($Config->{Website_libs});

use DBI;

use ECS::SQL;

my $dbh = ECS::SQL::connect();
my $dbhr = ECS::SQL::connect('SLAVE');

sub change{
	
	my $self = shift;
	my $input = shift;
	
	my $result = {
		'success'	=> 1,
		'update_DB'	=> $Config->{update_DB},
		'input'		=> $input
	};
	
	my $sql;
	my $sth;
	&exists_in_product($input);
	# IF only the productID differs...
	###-------------------------------
	if (($input->{new_productID} ne $input->{productID} ) and (uc($input->{new_partnumber}) eq uc($input->{partnumber}))){
		$input->{differ_code} = 1;
		if(!&update($input)){
			$result->{success} = 0;
			$result->{error} = "1";
			return $result;
		}
	}else{
		# IF only the partnumber differs...
		###--------------------------------
		if (($input->{new_productID} eq $input->{productID}) and (uc($input->{new_partnumber}) ne uc($input->{partnumber}))){
			$input->{differ_code} = 2;
			if(!&update($input)){
				$result->{success} = 0;
				$result->{error} = "2";
				return $result;
			}
		}else{
			# IF both productID AND partnumber differ...
			###-----------------------------------------
			if (($input->{new_productID} ne $input->{productID}) and (uc($input->{new_partnumber}) ne uc($input->{partnumber}))){
				$input->{differ_code} = 3;
				if(!&update($input)){
					$result->{success} = 0;
					$result->{error} = "3";
					return $result;
				}
			}else{
				# Nothing was changed??
				###--------------------
				$input->{nothing_changed} = "TRUE";
				$input->{differ_code} = 0;
				$result->{success} = 1;
				$result->{error} = "4";
			}
		}
	}
	return $result;
}

sub update{
	
	my $input = shift;
	# IF we want to update DB (Determined by API::Config)
	# --------------------------------------------------
	if ($Config->{update_DB}){
		###
		# Modify $LIMIT's value to scale the number of records updated at a time
		###---------------------------------------------------------------------
		my $LIMIT = 100;
		#$input->{differ_code} = 0; # Out of expected range
		if ( $input->{differ_code} == 1 ){
			&determine_problem($input);
			#update cart table with the values matched from the product table
			my $sql = "UPDATE cart SET productID = ? WHERE productID = ? LIMIT ?";
			my $app_sql = "UPDATE application SET productID = ? WHERE productID = ? LIMIT ?";
			my $appDesc_sql = "UPDATE applicationDescription SET productID = ? WHERE productID = ? LIMIT ?";
			my $appLog_sql = "UPDATE applicationLog SET productID = ? WHERE productID = ? LIMIT ?";
			my $appMatch_sql = "UPDATE matchingApplicationCategory SET productID = ? WHERE productID = ? LIMIT ?";
			my $appFilter_sql = "UPDATE filterGroup SET productID = ? WHERE productID = ? LIMIT ?";
			my $sth = $dbh->prepare($sql);
			my $app_sth = $dbh->prepare($app_sql);
			my $appDesc_sth = $dbh->prepare($appDesc_sql);
			my $appLog_sth = $dbh->prepare($appLog_sql);
			my $appMatch_sth = $dbh->prepare($appMatch_sql);
			my $appFilter_sth = $dbh->prepare($appFilter_sql);
			if (!$input->{problem}){
				$sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$app_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appDesc_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appLog_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appMatch_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appFilter_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				while ($sth->rows >= $LIMIT){
					$sth = $dbh->prepare($sql);
					$sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($app_sth->rows >= $LIMIT){
					$app_sth = $dbh->prepare($app_sql);
					$app_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appDesc_sth->rows >= $LIMIT){
					$appDesc_sth = $dbh->prepare($appDesc_sql);
					$appDesc_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appLog_sth->rows >= $LIMIT){
					$appLog_sth = $dbh->prepare($appLog_sql);
					$appLog_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appMatch_sth->rows >= $LIMIT){
					$appMatch_sth = $dbh->prepare($appMatch_sql);
					$appMatch_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appFilter_sth->rows >= $LIMIT){
					$appFilter_sth = $dbh->prepare($appFilter_sql);
					$appFilter_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
			}
		}elsif ( $input->{differ_code} == 2 ){
			&determine_problem($input);
			my $sql = "UPDATE cart SET partnumber = ? WHERE partnumber = ? LIMIT ?";
			my $sth = $dbh->prepare($sql);
			if (!$input->{problem}){
				$sth->execute( $input->{ product_PN }, $input->{ partnumber }, $LIMIT );
				while ($sth->rows >= $LIMIT){
					$sth = $dbh->prepare($sql);
					$sth->execute( $input->{ product_PN }, $input->{ partnumber }, $LIMIT );
				}
			}
		}elsif ( $input->{differ_code} == 3 ){
			&determine_problem($input);
			my $sql = "UPDATE cart SET productID = ?, partnumber = ? WHERE productID = ? LIMIT ?";
			my $app_sql = "UPDATE application SET productID = ? WHERE productID = ? LIMIT ?";
			my $appDesc_sql = "UPDATE applicationDescription SET productID = ? WHERE productID = ? LIMIT ?";
			my $appLog_sql = "UPDATE applicationLog SET productID = ? WHERE productID = ? LIMIT ?";
			my $appMatch_sql = "UPDATE matchingApplicationCategory SET productID = ? WHERE productID = ? LIMIT ?";
			my $appFilter_sql = "UPDATE filterGroup SET productID = ? WHERE productID = ? LIMIT ?";
			my $sth = $dbh->prepare($sql);
			my $app_sth = $dbh->prepare($app_sql);
			my $appDesc_sth = $dbh->prepare($appDesc_sql);
			my $appLog_sth = $dbh->prepare($appLog_sql);
			my $appMatch_sth = $dbh->prepare($appMatch_sql);
			my $appFilter_sth = $dbh->prepare($appFilter_sql);
			if (!$input->{problem}){
				$sth->execute( $input->{ product_PID }, $input->{ product_PN }, $input->{ productID }, $LIMIT );
				$app_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appDesc_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appLog_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appMatch_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				$appFilter_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				while ($sth->rows >= $LIMIT){
					$sth = $dbh->prepare($sql);
					$sth->execute( $input->{ product_PID }, $input->{ product_PN }, $input->{ productID }, $LIMIT );
				}
				while ($app_sth->rows >= $LIMIT){
					$app_sth = $dbh->prepare($app_sql);
					$app_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appDesc_sth->rows >= $LIMIT){
					$appDesc_sth = $dbh->prepare($appDesc_sql);
					$appDesc_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appLog_sth->rows >= $LIMIT){
					$appLog_sth = $dbh->prepare($appLog_sql);
					$appLog_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appMatch_sth->rows >= $LIMIT){
					$appMatch_sth = $dbh->prepare($appMatch_sql);
					$appMatch_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
				while ($appFilter_sth->rows >= $LIMIT){
					$appFilter_sth = $dbh->prepare($appFilter_sql);
					$appFilter_sth->execute( $input->{ product_PID }, $input->{productID}, $LIMIT);
				}
			}
		}
	     
	    if(!&writeLog($input)){
			return 0;
	    };
	}
    return 1;
}

###
# Problem codes for bad data (used by submit_change.html)
###------------------------------------------------------
sub determine_problem{
	my $input = shift;
	
	#compare (upper-cased) newly entered product numbers to existing (upper-cased) numbers from the product table
	if ( ($input->{new_productID} != $input->{product_PID}) && (uc($input->{new_partnumber}) ne uc($input->{product_PN})) ){
		$input->{problem} = 1;
	}elsif ( ($input->{new_productID} eq $input->{product_PID}) and (uc($input->{new_partnumber}) ne uc($input->{product_PN})) ){
		$input->{problem} = 2;
	}elsif ( ( uc($input->{new_partnumber}) eq uc($input->{product_PN}) ) and ($input->{new_productID} ne $input->{product_PID} ) ){
		$input->{problem} = 3;
	}elsif ( ( uc($input->{new_partnumber}) eq uc($input->{product_PN})) and ($input->{new_productID} eq $input->{product_PID}) ){
		$input->{problem} = 0;
	}else{
		print "Content-type: text/html\r\n\r\nUndetermined problem.";
	}
	return $input->{problem};
}

###
# Check product table for existing product
###------------------------------------
sub exists_in_product{
	my $input = shift;
	my $sql;
	$sql = "SELECT productID, partnumber
			FROM product 
			WHERE productID = ? OR partnumber = ?";
	my $sth = $dbhr->prepare($sql);
	$sth->execute($input->{new_productID}, $input->{new_partnumber});
	#set new input vars to the corresponding products from product table
	($input->{product_PID}, $input->{product_PN}) = $sth->fetchrow_array;
	return 1;
}

sub writeLog{
	
	my $input = shift;
	# This function is only called if update() succeeded
	my $employeeID = $input->{employee}->{'employeeID'};
	my $sql = "INSERT INTO cartAdminLog ( employeeID, oldPID, newPID, oldPN, newPN ) 
				VALUES ( '" . $employeeID . "', '" . $input->{productID} . "', '" . $input->{new_productID} . "', '" . $input->{partnumber} . "', '" . $input->{new_partnumber} . "' )";
	my $sth = $dbh->prepare($sql);
	my $touch_product_sql = "UPDATE product SET date_modified = NOW() WHERE productID IN (?,?)";
	my $touch_product = $sth->prepare( $touch_product_sql );
	unless ($input->{problem} ne 0){
		$touch_product->execute(@$input{qw/productID new_productID/});
		$sth->execute() or return 0;
	}
	return 1;
}
