package SB::SSO;

use strict;
use warnings;
use SB::Logging qw($Logger ERROR INFO DEBUG FATAL WARNING);
use SB::Defaults qw($CONFIG $SB_PREFIX);
use SB::Utils qw(run parsePlainConfig);
use SB::Messages;
require SB::DB;

BEGIN {
	use Exporter;
	our (@ISA, $VERSION, @EXPORT, @EXPORT_OK);
	$VERSION =  4.00;
	@ISA = qw(Exporter);
    @EXPORT    = qw();
    @EXPORT_OK = qw(enableSso unregisterApplication updateSsoApplicationData changeSsoServer exportUser importAdmin);
}

use constant SSO_DEFAULTS_FILE => '/etc/sso/defaults';
my $SSO_DEFAULTS;

INIT {
	 $SSO_DEFAULTS = parsePlainConfig(SSO_DEFAULTS_FILE);
}

sub registerApplication {
 	my $app_id = undef;
	my $code;
 	my $phpcli = $CONFIG->{"internal"}->{"phpcli_path"};
    my $ssoServer;
	$ssoServer = $CONFIG->{"sso"}->{"server"};
	$ssoServer = $SSO_DEFAULTS->{'SSOD_LOCATION'} unless $ssoServer;

	unless ($ssoServer) {
		$Logger->Log(FATAL, 
			"No SSO server specified and no default found in " 
			. SSO_DEFAULTS_FILE
			. ". Please specify SSO server address");
	}
	$Logger->Log(INFO, "By default SSO server is only accessible over HTTPS. Check server URL if the registration fails") unless ($ssoServer =~ m/^https/);

	# This is to the lousy PHP SOAP client
	$ssoServer .= '/' unless substr($ssoServer, -1) eq '/';
	$Logger->Log(DEBUG, "SSO server is at: $ssoServer");

	setCGIEnvironment();
	($app_id, $code) = run("$phpcli -q $SB_PREFIX/utils/sso.php register $ssoServer");
	unless ($code == 0) {
		$Logger->Log(FATAL, "Failed to register application in SSO");
		$app_id = undef;
	}
 	return $app_id;
}

sub unregisterApplication {
	my $phpcli = $CONFIG->{"internal"}->{"phpcli_path"};
	setCGIEnvironment();
	(undef, undef) = run("$phpcli -q $SB_PREFIX/utils/sso.php unregister");
}

sub updateSsoApplicationData() {
	my $phpcli = $CONFIG->{"internal"}->{"phpcli_path"};
	setCGIEnvironment();
	(undef, undef) = run("$phpcli -q $SB_PREFIX/utils/sso.php update");
}

sub changeSsoServer() {
	$Logger->Log(FATAL, "changeSsoServer not implemented");
	unregisterApplication();
	registerApplication();
}

sub exportUser($$$) {
	my ($oldUsername, $newUsername, $password) = @_;
	my $phpcli = $CONFIG->{"internal"}->{"phpcli_path"};
	my $associate = 0;
	if (substr($oldUsername, 0, 1) eq "+") {
		$associate = 1;
		substr($oldUsername, 0, 1) = "";
	}

	$Logger->Log(DEBUG, "Exporting $oldUsername -> $newUsername");
	my ($output, $code) = run($phpcli,
			"-q", "$SB_PREFIX/utils/sso.php", "exportuser",
			$associate, $oldUsername, $newUsername, $password);
	unless ($code == 0) {
		$Logger->Log(ERROR, "Failed to export user $oldUsername as $newUsername");
		return 1;
	}
	else {
		$Logger->Log(INFO, "Successfully exported user $oldUsername");
	}
	return 0;
}

sub importAdmin() {
	my $query;
	my $admin_sso_uid;
	if ($SSO_DEFAULTS && $SSO_DEFAULTS->{'SSOD_ADMIN_UID'}) {
        $admin_sso_uid = $SSO_DEFAULTS->{'SSOD_ADMIN_UID'};
    }
	if (!$admin_sso_uid) {
		$Logger->Log(ERROR, "SSOD_ADMIN_UID is not defined in " . SSO_DEFAULTS_FILE);
		return 1;
	}

 	my $dbh = SB::DB::getSBHandle() or return 1;
	$query =<<"EOQ";
		update user set
			sso_uid='$admin_sso_uid',
			is_local=0
		where parent_id=0
EOQ
	$dbh->do($query);
	$dbh->disconnect();

	return 0;
}

sub enableSso() {
    my $app_id = registerApplication();
}

sub setCGIEnvironment() {
	my $SERVER_NAME;
	my $SERVER_PORT;
	my $https;

	$Logger->Log(DEBUG, "Application URL: " . $CONFIG->{'general'}->{'application_url'});
	if ($CONFIG->{'general'}->{'application_url'} =~ m|^http(s)?://([-\.\w\d]+)(:\d+)?|i) {
		$https = $1;
		$SERVER_NAME = $2;
		$SERVER_PORT = $3 ? substr($3, 1) : ($https ? 443 : 80);
	}
	else {
		$SERVER_NAME = $CONFIG->{"internal"}->{'sb_host_ip'};
		$SERVER_PORT = 80;
		$Logger->Log(WARNING, "Invalid application URL, using http://$SERVER_NAME");
	}
	#$ENV{'SERVER_NAME'} = $CONFIG->{"internal"}->{'sb_host_ip'};
	$ENV{'HTTPS'} = $https ? 'on' : 'off';
	$ENV{'SERVER_NAME'} = $SERVER_NAME;
	$ENV{'HTTP_HOST'} = $SERVER_NAME;
	$ENV{'SERVER_PORT'} = $SERVER_PORT;
}

1;

