<?php

require_once('URCUDMLData.php');
require_once('ErrorDebug.php');
require_once('URCValues.php');

class URCAmazonData {

	var $funcType = '';
	var $systemId = -1;
	var $roomId = -1;

	function __construct($systemId) {		
		$this->systemId = $systemId;
	}

	public function curl_req($data, &$resultData, $timeoutSec)
	{
	    $ch = curl_init();

	    curl_setopt($ch, CURLOPT_URL, Config::get('editorenv.urcMCSAPPServerAddr'));
	    //curl_setopt($ch, CURLOPT_USERPWD, Config::get('editorenv.urcDBServerAddr'));
	    //curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
	    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	    
	    if($timeoutSec > 0) {
	    	curl_setopt($ch, CURLOPT_TIMEOUT, $timeoutSec);
	    }

	    //http_build_query
	    //if($req == 'POST') {
	    	curl_setopt($ch, CURLOPT_POST, true );
	    	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

			curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data)));
	    //}
		$resultData = curl_exec($ch);
	    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	    curl_close($ch);

	    //ErrorDebug::write($httpCode);

	    return $httpCode;
	}

	public function doFunc($funcType, $roomId) {

		$this->funcType = $funcType;
		$this->roomId = $roomId;

		if($this->funcType == 'create_service') {

			$result = $this->createService();
			if($result !== false) {
				return Response::json(array('result' => true, 'data' => $result));
			}
			else {
				return Response::json(array('result' => false, 'error' => 'fail to create the service'));
			}
		}

		if($this->funcType == 'delete_service') {

			if($this->deleteService() == true) {
				return Response::json(array('result' => true));
			}
			else {
				return Response::json(array('result' => false, 'error' => 'fail to delete the service'));
			}
		}

		if($this->funcType == 'send_email') {
			
			$result = $this->sendEmail();
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to send' ));
			}

			return Response::json(array('result' => true));
		}
		
		if($this->roomId < 0) {
			return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
		}
		
		if($this->funcType == 'get_scenes') {
			
			$scenes = $this->getScenes($this->roomId);
			
			return Response::json(array('result' => true, 'data' => $scenes));
		}

		if($this->funcType == 'get_scene') {

			$rules = array(
				'id' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	
			
			if($this->roomId < 0) {
				return Response::json(array('result' => false, 'error' => 'room Id is wrong'));
			}

			$id = Input::get('id');

			$result = $this->getScene($id);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to get' ));
			}

			return Response::json(array('result' => true, 'data' => $result));
		}

		if($this->funcType == 'del_scene') {
			
			$rules = array(
				'id' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	
			
			$id = Input::get('id');

			$result = $this->delScene($id);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => 'fail to delete' ));
			}

			return Response::json(array('result' => true));
		}

		if($this->funcType == 'create_scene') {
			
			$rules = array(
				'type' => 'Required',
				'spoken_text' => 'Required',
				'macro' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}	

			$type = Input::get('type');
			$spokenText = Input::get('spoken_text');
			$macro = Input::get('macro');

			$errMsg = '';
			$result = $this->createScene($type, $spokenText, $macro, $errMsg);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => $errMsg ));
			}

			return Response::json(array('result' => true));
		}

		if($this->funcType == 'set_scene') {
			
			$rules = array(
				'id' => 'Required',
				'type' => 'Required',
				'spoken_text' => 'Required',
				'macro' => 'Required');

			$v = Validator::make(Input::all(), $rules);
			if($v->fails()) {
				return Response::json(array('result' => false, 'error' => implode("\n", $v->messages()->all())));
			}

			$id = Input::get('id');
			$type = Input::get('type');
			$spokenText = Input::get('spoken_text');
			$macro = Input::get('macro');

			$errMsg = '';
			$result = $this->setScene($id, $type, $spokenText, $macro, $errMsg);
			if($result === false) {
				return Response::json(array('result' => false, 'error' => $errMsg));
			}

			return Response::json(array('result' => true));
		}

		return Response::json(array('result' => false, 'error' => 'unknown command'));
	}

	public function getServiceObj() {

		$system = $this->getExistService();
		if($system) {
			$amazon = new stdClass;
			$amazon->name = 'amazon_echo';
			$amazon->link_code = $system->link_code;
			return $amazon;
		}

		return null;
	}

	public function getExistService() {

		return DB::table('a_amazon_system')->where('system_id', '=', $this->systemId)->first();
	}

	public function generateLinkCode() {

		$data = StringGenerator::doGen(4, 'AZ');
		$num = StringGenerator::doGen(2, '09');

		return substr($data, 0, 2).$num.substr($data, 2);
	}

	public function registerToMCS($linkCode) {
		
		$masterBStation = DB::table('a_bstations')->where('system_id', '=', $this->systemId)->
			where('master', '=', 1)->first();
		if(!$masterBStation) {
			return false;
		}

		$regData  = new stdClass;
		
		$regData->Cmd = 'DsInfo';
		
		$regData->data = new stdClass;
		$regData->data->Model = $masterBStation->type;
		$regData->data->Module = 'Alexa';
		$regData->data->Password = $linkCode;
		$regData->data->MAC = $masterBStation->mac;

		$resultData = '';
		$httpCode = $this->curl_req(json_encode($regData), $resultData, 10);
		if($httpCode != 200) {
	   		return false;
		}

		$resultInfo = json_decode($resultData);
	    if(!isset($resultInfo->Sucess) || $resultInfo->Sucess !== true) {
	    	return false;
	    }

		return true;
	}
	
	public function createService() {
		
		$system = $this->getExistService();
		if($system) {
			unset($system->id);
			return $system;
		}

		$linkCode = $this->generateLinkCode();

		if(!$this->registerToMCS($linkCode)) {
			return false;
		}

		$serviceId = -1;

		try
		{
			DB::begintransaction();

			$serviceId = DB::table('a_amazon_system')->insertGetId(array('system_id' => $this->systemId, 'link_code' => $linkCode));
			URCSystemData::updateEditTime($this->systemId, '');

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();
			return false;
		}

		$system = new stdClass;
		$system->id = $serviceId;
		$system->system_id = $this->systemId;
		$system->link_code = $linkCode;
		return $system;
	}

	public function deleteService() {

		try
		{
			DB::begintransaction();
			
			DB::table('a_amazon_system')->where('system_id', '=', $this->systemId)->delete();
			DB::table('a_amazon_scene')->where('system_id', '=', $this->systemId)->delete();
			URCSystemData::updateEditTime($this->systemId, '');

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();
			return false;
		}

		return true;
	}

	public function getScenesAndInfo($roomId, &$scenes, &$infoBase64) {
		
		$infoArray = array();
		$scenes = DB::table('a_amazon_scene')->where('room_id', '=', $roomId)->get();
		
		foreach($scenes as $scene) {

			$cmd = "turn on";
			if($scene->type == 0) {
				$cmd = "turn off";
			}
			
			$item = array('ruleid' => "1", 'response' => "0", 
					'param' => 
						array(
							"0" => array('value' => $scene->spoken_text),
							"1" => array('value' => $cmd))
					);
			
		    $infoArray[(string)($scene->id)] = $item;

		    unset($scene->system_id);
			unset($scene->room_id);
			unset($scene->spoken_text);
			unset($scene->type);			
		}

		$infoBase64 = base64_encode(json_encode($infoArray, JSON_FORCE_OBJECT));
	}

	public function getScenes($roomId) {

		$chkExisting = DB::table('a_amazon_scene')->where('room_id', '=', $roomId)->get();
		foreach($chkExisting as $scene) {

			unset($scene->system_id);
			unset($scene->room_id);
		}

		return $chkExisting;
	}

	public function getScene($id) {
		
		$chkExisting = DB::table('a_amazon_scene')->where('room_id', '=', $this->roomId)->
			where('id', '=', $id)->first();

		if($chkExisting) {

			unset($chkExisting->system_id);
			unset($chkExisting->room_id);
			return $chkExisting;

		}
		
		return false;
	}

	public function delScene($id) {

		DB::table('a_amazon_scene')->where('room_id', '=', $this->roomId)->
			where('id', '=', $id)->delete();

		URCSystemData::updateEditTime($this->systemId, '');

		return true;
	}

	public function createScene($type, $spokenText, $macro, &$errMsg) {

		$existingData = DB::table('a_amazon_scene')->where('system_id', '=', $this->systemId)->
			where('type', '=', $type)->where('spoken_text', '=', $spokenText)->first();
		if($existingData) {
			$errMsg = 'This command is already being used in the system. Enter a different spoken command.';
			return false;
		}

		$jsonMacro = json_encode($macro);
		$sceneId = -1;

		try
		{
			DB::begintransaction();
			
			$sceneId = DB::table('a_amazon_scene')->insertGetId(array('room_id' => $this->roomId, 'system_id' => $this->systemId,
				'type' => $type, 'spoken_text' => $spokenText, 'macro' => $jsonMacro));
		
			URCSystemData::updateEditTime($this->systemId, '');
	
			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();
			$errMsg = 'fail to create the scene';
			return false;
		}

		return true;
	}

	public function setScene($id, $type, $spokenText, $macro, &$errMsg) {

		$existingData = DB::table('a_amazon_scene')->where('system_id', '=', $this->systemId)->
			where('type', '=', $type)->where('spoken_text', '=', $spokenText)->
			where('id', '<>', $id)->first();
		if($existingData) {
			$errMsg = 'This command is already being used in the system. Enter a different spoken command.';
			return false;
		}

		$jsonMacro = json_encode($macro);

		DB::table('a_amazon_scene')->where('room_id', '=', $this->roomId)->
			where('id', '=', $id)->
			update(array('type' => $type, 'spoken_text' => $spokenText, 'macro' => $jsonMacro));
	
		URCSystemData::updateEditTime($this->systemId, '');
	
		return true;
	}

	public function sendEmail() {

		$service = $this->getExistService();
		if(!$service) {
			return false;
		}

		$system = DB::table('a_systems')->where('id', '=', $this->systemId)->first();
		if(!$system) {
			return false;
		}
		$userDetail = UserDetail::where('user_id', '=', $system->user_id)->first();
		if(!$userDetail) {
			return false;
		}

		$masterBStation = DB::table('a_bstations')->where('system_id', '=', $this->systemId)->
			where('master', '=', 1)->first();
		if(!$masterBStation) {
			return false;
		}

		//$masterBStation->mac;
		//$service->link_code;

		$data = file_get_contents('./images/alexa_email.html');
		$data = str_replace('{{MAC Address}}', $masterBStation->mac, $data);
		$data = str_replace('{{Code}}', $service->link_code, $data);

		return EmailController::sendEmail($userDetail->user_email, "Welcome!", $data);
	}
}
