<?php
require_once 'MiMicCore.php';


class MiMicRemoteMcuInterface
{
	private $_mimic_host;
	private $_session_url;
	private $_bc_url_prefix;
	private $_last_update=null;
	private $_curl;

	/**
	 * @return hash array
	 *
	 */
	private static function parse_version_tag($i_s)
	{
		$t=preg_split('/[\s\/]+/',$i_s);
		$n=preg_split('/[\s\.]+/',$t[1]);
		return array('name'=>$t[0],'major'=>$n[0],'minor'=>$n[1]);
	}
	/**
	 * This function parses JSO response, confirms validation.
	 */
	private static function _isOnline_parseResponse($i_s)
	{
		$ret=json_decode($i_s);
		if(is_null($ret)){
			throw new MiMicException();
		}
		//"MiMicRemoteMCU/1.n;xならOK.(n>=1)
		$l=preg_split('/[\s;]+/',$ret->application);
		$rmcu=self::parse_version_tag($l[0]);//RemoteMcu
		$mcut=$l[1];//MCUTYPE
		$ret=(($rmcu['name']=="MiMicRemoteMCU") && ($rmcu['major']==1) && ($rmcu['minor']>=1));
		return $ret;
	}

	/**
	 * @param i_bh
	 * owner behaviour
	 * @param i_cbname
	 * callback function name for async xhr request.
	 */
	public function __construct($i_server)
	{
		$this->_mimic_host=$i_server;
		$this->_session_url='http://'.$this->_mimic_host.'/status.api';
		$this->_bc_url_prefix='http://'.$this->_mimic_host.'/mvm.api?v=1&bc=';
	}
	/**
	 * @return String
	 * response body string
	 */
	private function _xhrGet($i_url)
	{
		curl_setopt($this->_curl,CURLOPT_URL,$i_url);
		curl_setopt($this->_curl,CURLOPT_RETURNTRANSFER,1);
		curl_setopt($this->_curl,CURLOPT_HEADER, 0);
		$txt=curl_exec($this->_curl);
		if(!curl_errno($this->_curl)){
			if(curl_getinfo($this->_curl, CURLINFO_HTTP_CODE) === 200){
				return $txt;
			}
		}
		throw new MiMicException();
	}
	/**
	 * connectを試行する。
	 * 成功したら、定期的にperiodicUpdateを実行すること。
	 */
	public function connect()
	{
		//接続中ならおわり.
		if(is_null($this->_has_session!=null)){
			return;
		}
		$this->_curl = curl_init();
		//同期チェック.
		$res=$this->_xhrGet($this->_session_url);
		if(!self::_isOnline_parseResponse($res)){
			throw new MiMicException("Bad response from ".$this->_mimic_host);
		}
		$this->_last_update=time();
		return;
	}

	public function periodicUpdate()
	{
		$now=time();
		try{
			if(is_null($this->_last_update)){
				//connectionないんだけど？
				return false;
			}
			//以前の更新時間と比較して、期限内であれば、何もしない。
			if($now-$this->_last_update<5){
				return true;
			}
			//更新してみる
			$res=$this->_xhrGet($this->_session_url);
			if(!self::_isOnline_parseResponse($res)){
				throw new MiMicException();
			}else{
				//タイムスタンプの更新
				$this->_last_update=time();
			}
			return true;
		}catch(Exception $e){
			//例外は始末して非同期例外を生成.
		}
		$this->_last_update=null;
		return false;
	}
	/**
	 * @return void
	 */
	public function disconnect()
	{
		if($this->_last_update!=null){
			curl_close($this->_curl);
			$this->_last_update=null;//セッション監視wwwの削除.
		}else{
			//もはやnullなら何もしない.
			return;
		}
	}
	public function isConnected()
	{
		return !is_null($this->_last_update);
	}
	/**
	 * @return
	 * hash array
	 */
	public function execBc($i_bc)
	{
		$res_str=$this->_xhrGet($this->_bc_url_prefix.$i_bc);
		//print_r($i_bc."<br/>");
		//$res_str='{"version":"MiMicVM/1.2;Json/1.0","stream":"[]","result":"0"}';
		return $this->_parseMvmResult($res_str);
	}

	/**
	 * @return hash_array
	 * MiMicResultフォーマットのhashArray
	 */
	private function _parseMvmResult($i_mvmresult)
	{
		try{
			
			$ret=json_decode($i_mvmresult);
			if(is_null($ret))
			{
				throw new MiMicException();
			}
			//バージョンチェック
			{
				//MiMicVM/1.x;Json/1.0ならOK
				$l=preg_split("/[\s;]+/",$ret->version);
				if((strpos($l[0][0],'MiMicVM/1.')!=0) && ($l[1][1]!='Json/1.0')){
					throw new MiMicException();
				}
			}
			if(isset($ret->result)){
				if($ret->result!=0x0 || isset($ret->stream)){
					return $ret;
				}
			}
		}catch(Exception $e){
			throw new MiMicException("Invalid json");
		}
		throw new MiMicException();
	}

}


?>
