<?php
namespace Engine\GenDocument\Storage;

/**
 * Generalised interface for working with the DTM databases structure, handling both TINA objects and IRIX tables
 * @author Lucian
 */
class General
{
	protected $document = null;

	/*
	 * generate a string suitable for writing to a file (or sending it to the browser).
	 * this file should one be able to be loaded back into the template manager using importDocumentSaveData()
	 *
	 * $flags:
	 * 	- ['compress'] - gzencode the resulted string
	 * 	- ['encode'] - encode the resulted string ( NOTE: NOT IMPLEMENTED for now )
	 * 	- [''] ... not used
	*/
	public function generateDocumentSaveData($flags=[])
	{

		/* disabled for now. This would allow locking the template name to a certain applaication,
		 * 	by using its name
		global $APP_NAME;
		$encodeKey="DTM exporter from ".$APP_NAME." 'secret' key";
		*/
		$encodeKey='';

		$addUser = 		$this->getUser('addUser');
		$modUser = 		$this->getUser('modUser');
		$exportUser = 	$this->getUser('currentUser');

		// all data is gathered right now, start generating the output string
		$result=[];

		$page = new \DTMDocument();

		if (!$this->document) {
			throw new \Exception("Document template is not defined. You need to call the method loadTemplate before.");
		}

		$page->importFromStorage($this->document->templateContent);

		$result['page'] = 				serialize($page->exportToStorage(['mysql'=>true]));
		$result['fieldsDetails'] = 		serialize($this->document->fieldsDetails);
		$result['customFieldsDetails']= serialize($this->document->customFieldsDetails);

		$result['documentLength'] = 	strlen($result['page']).'.'.md5($result['page'].$encodeKey);
		$result['documentVersion'] = 	$page->version;

		$result['author'] = 			$addUser.','.$modUser;
		$result['date'] = 				time();
		$result['documentType'] = 		$this->document->docType;
		$result['pivot'] = 				\App\Config\IssueDocuments::getInstance()->getDocPivot($this->document->docType);
		$result['name'] = 				$this->document->name;

		$result['exporter'] = 			$exportUser;

		$result['documentFlags']['compressed']= (bool)$flags['compress'];
		$result['documentFlags']['encoded'] = 	(bool)$flags['encode'];

		$header ="DCS.DTM\0";	// file signature

		$footer="";

		$body=[];
		$body['documentVersion'] = 	$result['documentVersion'];
		$body['documentLength'] = 	$result['documentLength'];
		$body['date'] = 			$result['date'];
		$body['pivot'] = 			$result['pivot'];
		$body['name'] = 			$result['name'];
		$body['documentType'] = 	$result['documentType'];
		$body['flags'] = 			sprintf("%d%d%d%d", (int)$result['documentFlags']['compressed'], (int)$result['documentFlags']['encoded'], 0, 0);
		$body['author'] = 			$result['author'];
		$body['exporter'] = 		$result['exporter'];

		$body['fieldsDetails_length'] = 	strlen($result['fieldsDetails']);
		$body['customFieldsDetails_length']=strlen($result['customFieldsDetails']);
		$body['page_length'] = 				strlen($result['page']);

		$body['fieldsDetails'] = 		$result['fieldsDetails'];
		$body['customFieldsDetails'] = 	$result['customFieldsDetails'];
		$body['page'] = 				$result['page'];

		$bodyStr = 		serialize($body);
		if($flags['compress']){	// a compress was requested.. so compress it
			$bodyStr = 	gzdeflate($bodyStr, 9);
		}

		$header.= $body['flags'] . "\0";
		$header.= strlen($bodyStr) . "\0";

		return $header.$bodyStr.$footer;
	}


	/*
	 * importDocumentSaveData - transform a string generated by generateDocumentSaveData() to a valid Document() and return all saved flags
	 * this function is expected to get in $templateContent the exact output from generateDocumentSaveData()
	 *
	 * return the imported data as a new DTMDocument() (an assoc array containing all fields) or an error string
	*/
	public function importDocumentSaveData($templateContent)
	{
		/* disabled for now. This would allow locking the template name to a certain application,
		 * 	by using its name
		global $APP_NAME;
		$encodeKey="DTM exporter from ".$APP_NAME." 'secret' key";
		*/
		$encodeKey = '';

		$template = $templateContent;

		// $templateContent must begin with DCS.DTM\0 $bodyLength $footer (footer can be ignored)
		$header = substr($templateContent,0,8);
		if($header!="DCS.DTM\0") return "invalid file";
		$template = substr($templateContent,8);

		$templateFlags = 	substr($template,0 , 4);
		$templateFlags = 	str_split($templateFlags,1);
		$template = 		substr($template,5);

		// next item should be the length of the body region
		$bodyLength = 		(int)substr($template,0,8);
		$template = 		substr($template,strpos($template,"\0")+1);

		$body = 	substr($template,0,$bodyLength);

		/*
		 * try to detect any compressed or encoded file
		*
		* field format:
		*  	compressed - encoded - [..]not used [..]
		*/
		if($templateFlags[0]){ // the body is compressed, we must uncompress it first
			$body = gzinflate($body);
		}

		$body = unserialize($body);

		$page = new \DTMDocument();
		$documentVersion = explodeClean('.',$body['documentVersion']);
		$thisDocumentVersion = explodeClean('.',$page->version);

		// if the base versions for the class differs, then deny going forward. we must stop here
		if($documentVersion[0]!=$thisDocumentVersion[0]) return "incompatible document versions";

		// sanity checks for the file.
		$body['documentLength'] = explode(".",$body['documentLength']);
		if($body['documentLength'][0]!=strlen($body['page'])) return "corrupted file(size)";
		if($body['documentLength'][1]!=md5($body['page'].$encodeKey)) return "corrupted file";

		$result=[];
		$result['exportTime'] = 	$body['date'];
		$result['documentName'] = 	$body['name'];
		$result['documentType'] = 	$body['documentType'];
		$result['documentPivot'] = 	$body['pivot'];
		$result['documentAuthor'] = explode(",",$body['author']);
		$result['documentExporter']=$body['exporter'];

		$result['fieldsDetails'] = 		unserialize($body['fieldsDetails']);
		$result['customFieldsDetails']= unserialize($body['customFieldsDetails']);

		// $page->importFromStorage($body['page']);
		$result['page'] = 		unserialize($body['page']);

		return $result;
	}


	/**
	 * Load a template. Return an object
	 * @param int $idTemplate
	 * @return object
	 */
    public function loadTemplate($idTemplate)
    {
    	throw new \Exception("This function should be implemented");
    }

    /**
     * Updates an existing template
     * @param $idTemplate
     * @param $templateDataArr
     */
    public function updateTemplate($idTemplate, $templateDataArr)
    {
    	throw new \Exception("This function should be implemented");
    }

    /**
     * Get a specific user related to the loaded template
     * @param $which
     */
    public function getUser($which = 'addUser')
    {
    	throw new \Exception("This function should be implemented");
    }
}
