#!/usr/bin/perl -Tw -I. -I/usr/local/positive/Perl

use strict;
use Pos::Webtop::Web::ModuleLoader;
use CGI qw/:standard/;
use CGI::Cookie ();
use Digest::MD5();
use Pos::WebService::Modules::MyCalls;
use Pos::WebService::Modules::ParseServerXmlResponse;
use LWP::UserAgent;
use HTTP::Request;
use Config::General;
use URI::Escape;
use HTML::Entities;
use MIME::Base64;

my $conf = new Config::General("/usr/local/positive/conf/WebService.conf");
my %config = $conf->getall;

my $tb = Pos::Webtop::Toolbox->new();
my $client = $tb->getClient();
my $cgi = $tb->getCgi();
my $myCallsObj = Pos::WebService::Modules::MyCalls->new();
my $xmlResponseParserObj = Pos::WebService::Modules::ParseServerXmlResponse->new();
my $un = $cgi->param('un');
my $pw = $cgi->param('pw');
my $sn = $cgi->param('sn');
my $os = $cgi->param('os');
my $mt = $cgi->param('mt');
my $err;
$err = undef unless $cgi->param('err') and $err = $cgi->param('err');

# we have a login request..
my $db = $tb->getWebtopDbReader();
my $expired;
my $isTrialExpired;
my $userId;
my $existing = 0;
my $result = "FAILED";
my $reason = "UNAUTHORIZED";

# first param is the secret, second is the username
sub processConfig {
	my ($s,$un,$sId) = @{{@_}}{qw/secret un secretId/};
	my $netconnect = "/usr/local/positive/WebInterface/PositiveProVPN.networkConnect";
	open(CONFIG, $netconnect) || die ("Cound not open file!");
	my @data = <CONFIG>;
	close(CONFIG);

	# replace the secret and username
	foreach my $line (@data) {
		$line =~ s/PPROSECRET/$s/;
		$line =~ s/USERNAME/$un/;
		$line =~ s/SECRETID/$sId/;
	}
	
	return @data;
}

# takes the $userid, $sn, $os, $mt
sub storeMachineData {
	warn "insert row for machine $_[1], $_[2], $_[3], $_[4], 1\n";
	my $wtDb = $_[0];
	$wtDb->do( sql => "
			insert into 
				osx_machines 
					(u_id, serial_number, osx_version, machine_type, created_date, status)
			values 
				($_[1], '$_[2]', '$_[3]', '$_[4]', NOW(), 1);
			");
	$wtDb->commit();

	#warn "STORED MACHINE DATA\n\n";
}

sub updateMachineData {
	my $wtDb = $_[0];
	$wtDb->do( sql => "
			update
				osx_machines 
			set
				u_id=$_[2], serial_number='$_[3]', osx_version='$_[4]', machine_type='$_[5]', modified_date=NOW(), status=1
			where 
				machine_id=$_[1];
			");

	$wtDb->commit();

	#warn "UPDATED MACHINE DATA ID $_[1]\n\n";
}

sub getMachineIdForSerialNum {
	my $wtDb = $_[0];
	my ($mExId) = $wtDb->query( sql => "
			select  
				machine_id 
			from 
				osx_machines 
			where
				serial_number='$_[1]'
			order by machine_id desc limit 1
			");

	#warn "EXISTING MACHINEID $mExId\n\n";
	return $mExId;
}

sub storeRequestData {
	my $wtDb = $_[0];
	my $machId = $_[1];
	#if(!$machId) {
	#	$machId = 1;
	#}
	$machId = 1 unless ( defined( $machId ) && length( $machId ) > 0 );

	my $requestStr = "user=$_[2]&pwd=$_[3]&sn=$_[4]&os=$_[5]&mt=$_[6]";
	$wtDb->do( sql => "
			insert into 
				osx_requests (machine_id, request, result, reason, request_date)
			values ($machId, '$requestStr', '$_[7]', '$_[8]' ,NOW())
			");
	$wtDb->commit();

	#warn "REQUESTID stored\n\n";
}

sub getSharedSecret {
	my $wtDb = $_[0];
	my ($sec) = $wtDb->query( sql => "
			select
				shared_secret
			from
				osx_security_keys
			where
				status=1
			order by security_key_id desc limit 1
			");
	return $sec;
}

sub getSharedSecretId {
	my $wtDb = $_[0];
	my ($id) = $wtDb->query( sql => "
		select
			security_key_id
		from
			osx_security_keys
		where
			status=1
		order by security_key_id desc limit 1
		");

		return $id;
}

if (defined($un) && length($un))
{
	my $r = "
	<root>
		<type>Request</type>
		<remoteRequestor>
			<ipAddress></ipAddress>
			<datetime></datetime>
			<key></key>
			<sessionId></sessionId>
		</remoteRequestor>
		<command>
			<operation>UserOperator</operation>
			<method>checkUser</method>
		</command>
		<parameters>
			<parameterCount>2</parameterCount>
			<parameter>
				<name>uslId</name>
				<value></value>
			</parameter>
			<parameter>
				<name>uUserName</name>
				<value>$un</value>
			</parameter>
			<parameter>
				<name>uPwd</name>
				<value>$pw</value>
			</parameter>
		</parameters>
	</root>
	";

	my $request = HTTP::Request->new(GET => $config{webserviceurl} . "?r=$r" );
	
	my $ua = LWP::UserAgent->new;
	my $response = $ua->request( $request );
	
	if ($response)
	{
		$xmlResponseParserObj->parseResponse( response => $response->content ) or warn "mclservice:COULD NOT PARSE XML FROM CHECKUSER()\n\n";	
	}
	else
	{
		warn "mclservice:COULD NOT PARSE XML FROM CHECKUSER()\n\n";
	}
	
	if (lc($xmlResponseParserObj->getMessageInfoText()) eq "ok")
	{
		($userId) = $db->query( sql => "
			select 
				user_id
			from 
				users
			where
				upper(user_name) = '" . uc( $db->escape( dirty => $un ) ) . "'
			");

			#warn "USERID $userId\n\n";
	}

	$isTrialExpired = $xmlResponseParserObj->getMessageInfoTrialExpired();
}

#
#	if there is a userId then it seems to be a valid user
#	so lets go
#   will store the userid in the database along with the other passed in params
if(defined($userId) and length($userId) && !$isTrialExpired)
{
	# does the user have vpn access and can the user receive the OS X configuration
	my $userHasL2tpVPNAccess = $client->isOsxAccessEnabled(db=> $db, userId=>$userId);
	my $secret = getSharedSecret($db);
	my $secretId = getSharedSecretId($db);
	if($userHasL2tpVPNAccess and $secret) {
		my @vpnConfig = processConfig( secret => $secret, un => $un, secretId => $secretId);
		$result = "SUCCESS";
		$reason = "";
		my $existing = getMachineIdForSerialNum($db, $sn);
		if($existing) {
			updateMachineData($db, $existing, $userId, $sn, $os, $mt);
		} else {
			storeMachineData($db, $userId, $sn, $os, $mt);
			$existing = getMachineIdForSerialNum($db, $sn);
		}
		storeRequestData($db, $existing, $un, $pw, $sn, $os, $mt, $result, $reason);

		print "Content-type: x-application/text\n\n";
		print @vpnConfig;
	} else {
		$reason = "ERROR";
		storeRequestData($db, $existing, $un, $pw, $sn, $os, $mt, $result, $reason);
		print "Content-type: text/plain\n\n$result"; 
	}
} else {
	warn "mclservice: ERROR: user $userId does not exist\n";
	storeRequestData($db, $existing, $un, $pw, $sn, $os, $mt, $result, $reason);
	print "Content-type: text/plain\n\n$result";
}

1;
