<?php
$sha1 = 'testOutput';
$zipName = $sha1 . '.zip';
$game = 'd2';

$zip = new ZipArchive;
$res = $zip->open("test2.zip");

if ($res !== true) {
	header('400 Bad Request');
	echo 'Uploaded file not a valid Zip.';
	exit;
}

if ($game == 'd2') {
	
	$mapData = null;
	$isValidMapData = 0;
	$iniData = null;
	$isValidIniData = 0;
	$misData = null;
	$isValidMisData = 0;
	
	$zip->extractTo("duneMapTemp/");
	
	for ($i = 0; $i < 3; $i++) {
		
		$tmp = $zip->statIndex($i);		
		
		if (is_array($tmp) && preg_match('/\.map$/i', $tmp['name'])) {
			
			$mapData = $zip->getFromIndex($i);
			
			if ($mapData !== null) {
				
				$isValidMapData = isDuneMapFileValid("duneMapTemp/"."/".$tmp['name'], $tmp['size']);				 
			}
		} else if (is_array($tmp) && preg_match('/\.ini$/i', $tmp['name'])) {
			
			$iniData = $zip->getFromIndex($i);
			
			if ($iniData !== null) {
				$isValidIniData = isDuneIniFileValid("duneMapTemp/"."/".$tmp['name'], $tmp['size']);
			}
		} else if (is_array($tmp) && preg_match('/\.mis$/i', $tmp['name'])) {
			
			$misData = $zip->getFromIndex($i);
			
			if ($misData !== null) {
				$isValidMisData= isDuneMisFileValid("duneMapTemp/"."/".$tmp['name'], $tmp['size']);
			}
		}
	}
	
	deleteDuneMapTempDir("duneMapTemp/");
	
	if ($mapData === null || $isValidMapData === 0) {
		header('400 Bad Request');
		echo 'Valid map file not found in Zip.';
		exit;
	}
	
	if ($iniData === null || $isValidIniData === 0) {
		header('400 Bad Request');
		echo 'Valid map ini file not found in Zip.';
		exit;
	}
	
	if ($misData !== null && $isValidMisData === 0) {
		header('400 Bad Request');
		echo 'Valid map mis file not found in Zip.';
		exit;
	}
	
	//  if ($sha1 != sha1($mapData . $iniData . $misData)) {
	//      header('400 Bad Request');
	//      echo 'Map file checksum differs from Zip name, rejected.';
	//      exit;
	//  }
	
	$res = $zip->open($zipName, ZipArchive::CREATE);
	if ($res !== true) {
		header('500 Internal Server Error');
		echo 'Server failed to save map zip, sorry.';
		exit;
	}
	
	$zip->addFromString($sha1 . '.map', $mapData);
	
	$zip->addFromString($sha1 . '.ini', $iniData);
	
	if ($misData) {
		$zip->addFromString('_' . $sha1 . '.mis', $misData);
	}
	$zip->close();
	
	echo 'Upload succeeded!';
	exit;
}


function deleteDuneMapTempDir($dirname) {
	if (is_dir($dirname)){
		
		$dir_handle = opendir($dirname);
	}

	if (!$dir_handle) {
		
		return false;
	}
	
	while($file = readdir($dir_handle)) {
		if ($file != "." && $file != "..") {			
			if (!is_dir($dirname."/".$file)){
				unlink($dirname."/".$file);
			} else {
				delete_directory($dirname.'/'.$file);
			}
		}
	}
	
	closedir($dir_handle);
	
	rmdir($dirname);
	
	return true;	
}

/**
 * This function validates Dune map file.
 *
 * @param $filePath Path to the map file.
 * @param $fileSize Size of the map file.
 * @return number 1 if map is valid, 0 otherwise.
 */
function isDuneMapFileValid($filePath, $fileSize) {
	
	$returnVal = 1;
	
	$handle = fopen($filePath, "rb");
	
	$height = unpack('s', fread($handle, 2))[1];
	$width = unpack('s', fread($handle, 2))[1];
	
	// Check if height is valid.
	if ($height > 128)
	{
		$returnVal = 0;
	}
	
	// Check if width is valid.
	if ($width > 128)
	{
		$returnVal = 0;
	}
	
	// Check if file size is valid.
	if (($height * $width * 4) + 4 != $fileSize)
	{
		$returnVal = 0;
	}
	
	$cellCount = $height * $width;
	
	if ($returnVal == 1)
	{
		// Check if all cells are valid.
		for ($iter = 1; $iter<= $cellCount; $iter++)
		{
			$tile = unpack('s', fread($handle, 2))[1];
			
			//Check tile index value of the cell.
			if ($tile >= 800)
			{
				$returnVal = 0;
				break;
			}
			
			$special = unpack('s', fread($handle, 2))[1];
			
			//Check special index value of the cell.
			if ($special >= 1000)
			{
				$returnVal = 0;
				break;
			}
		}
	}
	
	fclose($handle);
	
	return $returnVal;
}

/**
 * This function validates Dune ini file.
 *
 * @param $iniPath Path to the ini file.
 * @param $fileSize Size of the ini file.
 * @return number number 1 if ini file is valid, 0 otherwise.
 */
function isDuneIniFileValid($filePath, $fileSize) {
	
	$returnVal = 1;
	
// 	if (strcmp(mime_content_type($filePath),"text/plain") != 0) {
		
// 		$returnVal = 0;
// 	}
	
	if ($fileSize > 2000) {
		
		$returnVal = 0;
	}
	
	return $returnVal;
}

/**
 * This function validates Dune mis file.
 *
 * @param $filePath Path to the ini file.
 * @param $fileSize Size of the ini file.
 * @return number number 1 if ini file is valid, 0 otherwise.
 */
function isDuneMisFileValid($filePath, $fileSize) {
	
	$returnVal = 1;
	
	// Check if .mis file size is 68066.
	if ($fileSize!= 68066) {
		
		$returnVal = 0;
	}
	
	return $returnVal;
}

?>