<?php

// Kickstart the framework
// $f3=require('lib/base.php');
require_once './vendor/autoload.php';

date_default_timezone_set('Europe/Budapest');
$f3 = \Base::instance();
$f3->set('DB',new DB\Jig('data/'));
$db=new \DB\Jig('data/');
class Item extends \DB\Jig\Mapper {
    public function __construct() {
        parent::__construct( \Base::instance()->get('DB'), 'items' );
    }
}
$f3->set('DEBUG',1);
if ((float)PCRE_VERSION<8.0)
	trigger_error('PCRE version is out of date');

// Load configuration
$f3->config('config.ini');

$f3->route('GET /',
		function($f3) {
			$f3->set('template', 'home.htm');
			echo View::instance()->render('layout.htm');
		 }
);
$f3->route('GET /admin',
		function($f3) {
			$f3->set('template', 'home.htm');
			$f3->set('admin', true);
			echo View::instance()->render('layout.htm');
		 }
);
$f3->route('GET /add',
		function($f3) {
			$f3->set('template', 'add.htm');
			echo View::instance()->render('layout.htm');
		 }
);
$f3->route('POST /add',
		function($f3) use ($db) {
			$item =new Item;
			$item->copyFrom(json_decode($f3->get('BODY')));
			$item->save();

		 }
);

$f3->route('GET /api/items', 
	function($f3) {
		$item = new Item;
		$items = $item->find();
		$list = array_map([$item, 'cast'],$items);
		echo json_encode($list);
		}
	);

$f3->route('POST /sendsignal', function($f3) {
	$post = json_decode($f3->get('BODY'), true);
	$messages = sendsignal($post);
	echo json_encode($messages);
});

function sendsignal($post) {
	$iparray = preg_split('/\r\n|\r|\n/', $post['item']['ip']);
	$macArray = preg_split('/\r\n|\r|\n/', $post['item']['macAddress']);
	$label = $post['label'];
	$messages = [];
	switch ($post['item']['channel']) {
		case 'telnet':
			foreach ($iparray as $ip) {
				$result = telnet($ip, $post['item']['port'], $post['action']);
				array_push($messages, $result);
			}
			break;
		case 'udp':
			foreach ($iparray as $ip) {
				$result = udp($ip, $post['item']['port'], $post['action']);
				array_push($messages, $result);
			}
			break;
		case 'wol':
			if ($label === 'on') {
				foreach ($macArray as $mac) {
					$result = wol($mac, $post['item']['broadcastIP']);
					array_push($messages, $result);
				}
				
			} else {
				foreach ($iparray as $ip) {
					$result = shutdown($ip);
					array_push($messages, $result);
				}
			}

			break;
		default:
			array_push($messages, ['success' => false, 'message' => 'No channel set for these equipments']);
			break;
	}
	return $messages;
}

$f3->route('POST /del', function ($f3) {
		$item = new Item;
		$target = json_decode($f3->get('BODY'), true);
		$items = $item->load(['@name = ?', $target['name']]);
		$items->erase();
		echo json_encode(['success' => true, 'message' => 'Deleted']);

});

function telnet($ip, $port, $action) {
		try {
			$factory = new \Socket\Raw\Factory();
			$socket = $factory->createClient($ip . ':' . $port, 2);
	        $client = \Graze\TelnetClient\TelnetClient::factory();
	        $client->setSocket($socket);
	        // $dsn = '192.168.0.100:23';
	        $client->setLineEnding(null);
	        $client->setPrompt("Optoma_PJ>");
	        $client->setPromptError("F");
	        try {
	        	$conn = $client->connect($ip . ':' . $port);	
	        	$client->setReadTimeout(1);
	        	$response = $client->execute($action . "\r"); 	
	        	return ['success' => true, 'message' => 'successfully sent command to ' . $ip];
	        } catch (Exception $e) {
	        	return ['success' => false, 'message' => $e->getMessage() . $ip];
	        }
			
		} catch (Exception $e) {
			return ['success' => false, 'message' => $e->getMessage() . ' ' . $ip];			
		}

}

function udp($ip, $port, $action) {
        if ($socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) {
            socket_sendto($socket, $action, strlen($action), 0, $ip, $port);
        	return ['success' => true, 'message' => 'UDP successful'];
        } else {
          	return ['success' => false, 'message' => 'UDP not sent...'];
        }

}


function shutdown($ip) {
	$ipdata = explode('@', $ip);
	$username = explode(':', $ipdata[0])[0];
	$password = explode(':', $ipdata[0])[1];
	$ipaddress = $ipdata[1];
	$output = shell_exec("net rpc shutdown -f -t 0 -C 'message' -U ". $username . "%" . $password ." -I " . $ipaddress);
	return ['success' => true, 'message' => $output . '(' . $ipaddress . ')'];
}

function wol($macAddress, $broadcastIP) {
	$f = new \Phpwol\Factory();
	$magicPacket = $f->magicPacket();
	$result = $magicPacket->send($macAddress, $broadcastIP);
	if ($result) {
		return ['success' => true, 'message' => 'Successful Wake On Lan for ' . $macAddress];
	} else {
		return ['success' => false, 'message' => 'Unsuccessful WOL for MAC address ' . $macAddress];
	}
}

$f3->route('GET /cron', function($f3) {
	$datestring = date('H').':'.date('i');
	$model = new Item;
	$items = $model->find(['@ontime = ? or @offtime = ?', $datestring, $datestring]);
	
	if (!empty($items)) {
		$messages = [];
		foreach ($items as $item) {
			if (in_array(date('l'), $item['days'])) {
				if ($item['ontime'] === $datestring) { $messages = sendsignal(['item' => $item, 'action' =>$item['oncommand']]);}
				if ($item['offtime'] === $datestring) { $messages = sendsignal(['item' => $item, 'action' =>$item['offcommand']]);}
			}
		}
		foreach ($messages as $message) {
			// echo date('Y.m.d'). ' ' .$datestring . ' '. $message['message'];
			$logger = new Log('cron.log');
			$logger->write( $message['message']);
		}

	}
});


$f3->run();