<?php

if (!isset($_REQUEST['id'])) {
	throw new SimpleSAML_Error_BadRequest('Missing required parameter: id');
}
$id = (string)$_REQUEST['id'];

if (isset($_REQUEST['type'])) {
	$type = (string)$_REQUEST['type'];
	if (!in_array($type, array('init', 'js', 'nojs', 'embed'), TRUE)) {
		throw new SimpleSAML_Error_BadRequest('Invalid value for type.');
	}
} else {
	$type = 'init';
}

if ($type !== 'embed' && $type !== 'async') {
	SimpleSAML_Logger::stats('slo-iframe ' . $type);
	SimpleSAML_Stats::log('core:idp:logout-iframe:page', array('type' => $type));
}

// sanitize the input
$sid = SimpleSAML_Utilities::parseStateID($id);
if (!is_null($sid['url'])) {
	SimpleSAML_Utilities::checkURLAllowed($sid['url']);
}

$state = SimpleSAML_Auth_State::loadState($id, 'core:Logout-IFrame');
$idp = SimpleSAML_IdP::getByState($state);

if ($type !== 'init') {
	/* Update association state. */

	$associations = $idp->getAssociations();

	foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {

		$spId = sha1($assocId);

		/* Move SPs from 'onhold' to 'inprogress'. */
		if ($sp['core:Logout-IFrame:State'] === 'onhold') {
			$sp['core:Logout-IFrame:State'] = 'inprogress';
		}

		/* Check for update through request. */
		if (isset($_REQUEST[$spId])) {
			$s = $_REQUEST[$spId];
			if ($s == 'completed' || $s == 'failed') {
				$sp['core:Logout-IFrame:State'] = $s;
			}
		}

		/* Check for timeout. */
		if (isset($sp['core:Logout-IFrame:Timeout']) && $sp['core:Logout-IFrame:Timeout'] < time()) {
			if ($sp['core:Logout-IFrame:State'] === 'inprogress') {
				$sp['core:Logout-IFrame:State'] = 'failed';
			}
		}

		/* In case we are refreshing a page. */
		if (!isset($associations[$assocId])) {
			$sp['core:Logout-IFrame:State'] = 'completed';
		}

		/* Update the IdP. */
		if ($sp['core:Logout-IFrame:State'] === 'completed') {
			$idp->terminateAssociation($assocId);
		}

		if (!isset($sp['core:Logout-IFrame:Timeout'])) {
			if (method_exists($sp['Handler'], 'getAssociationConfig')) {
				$assocIdP = SimpleSAML_IdP::getByState($sp);
				$assocConfig = call_user_func(array($sp['Handler'], 'getAssociationConfig'), $assocIdP, $sp);
				$sp['core:Logout-IFrame:Timeout'] = $assocConfig->getInteger('core:logout-timeout', 5) + time();
			} else {
				$sp['core:Logout-IFrame:Timeout'] = time() + 5;
			}
		}
	}
}

if ($type === 'js' || $type === 'nojs') {
	foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {

		if ($sp['core:Logout-IFrame:State'] !== 'inprogress') {
			/* This SP isn't logging out. */
			continue;
		}

		try {
			$assocIdP = SimpleSAML_IdP::getByState($sp);
			$url = call_user_func(array($sp['Handler'], 'getLogoutURL'), $assocIdP, $sp, NULL);
			$sp['core:Logout-IFrame:URL'] = $url;
		} catch (Exception $e) {
			$sp['core:Logout-IFrame:State'] = 'failed';
		}
	}
}

$id = SimpleSAML_Auth_State::saveState($state, 'core:Logout-IFrame');

$globalConfig = SimpleSAML_Configuration::getInstance();

if ($type === 'nojs') {
	$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:logout-iframe-wrapper.php');
	$t->data['id'] = $id;
	$t->data['SPs'] = $state['core:Logout-IFrame:Associations'];
	$t->show();
	exit(0);
}

$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:logout-iframe.php');
$t->data['id'] = $id;
$t->data['type'] = $type;
$t->data['from'] = $state['core:Logout-IFrame:From'];
$t->data['SPs'] = $state['core:Logout-IFrame:Associations'];
$t->show();
exit(0);
