<?php

namespace SHServ\Models;

use \SHServ\Tools\DeviceScanner;
use \SHServ\Tools\DeviceAPI\Base;
use \SHServ\Entities\Device;
use \SHServ\Entities\DeviceAuth;

class Devices extends \SHServ\Middleware\Model {
	public function connect_new_device(String $device_ip, String $alias = "", String $name = "") {
		// validate device

		$device_api = new Base($device_ip);
		$device_info = $device_api -> get_about();
		if(!$device_info["data"]) {
			return false;
		}

		if($device_info["data"]["status"] != "setup") {
			return false;
		}

		// create in table devices

		$device_id = app() -> thin_builder -> insert(Device::$table_name, [
			"alias" => $alias,
			"name" => $name,
			"device_type" => $device_info["data"]["device_type"],
			"device_name" => $device_info["data"]["device_name"],
			"device_ip" => $device_info["data"]["ip_address"],
			"device_mac" => $device_info["data"]["mac_address"],
			"device_hard_id" => $device_info["data"]["device_id"],
			"firmware_version" => $device_info["data"]["firmware_version"],
			"connection_state" => "active",
			"state" => "active",
			"description" => "",
			"last_contact" => date("Y-m-d H:i:s"),
			"create_at" => date("Y-m-d H:i:s")
		]);

		$device = $device_id ? new Device($device_id) : null;

		if(!$device) {
			return false;
		}

		// generate token
		
		$device_token = app() -> utils -> generate_token(16); 
		
		// create in table device_auth
		
		$device_auth = app() -> thin_builder -> insert(DeviceAuth::$table_name, [
			"device_id" => $device -> id(),
			"device_token" => $device_token,
			"server_token" => "",
			"state" => "active",
			"create_at" => date("Y-m-d H:i:s")
		]);

		if(!$device_auth) {
			return false;
		}

		$device -> set_device_token($device_token);

		return $device;
	}

	public function remove_device(int $device_id): bool {
		// create device entity
		
		$result = app() -> thin_builder -> select(
			Device::$table_name, 
			Device::get_fields(), 
			[ ["id", "=", $device_id] ]
		);

		if(!$result) {
			return false;
		}

		$device = new Device($result[0]["id"], $result[0]);

		// reset device
		
		if(!$device -> get_device_api() -> reset()) {
			return false;
		}
		
		// state killed in device_auth table
		
		$device_auth = $device -> get_auth();
		if(!$device_auth) {
			return false;
		}

		$device_auth -> kill();

		// remove from devices
		
		return $device -> remove() ? true : false;
	}

	public function get_device_list(): Array {
		// get from db table devices with state = "active"
		
		$raw_devices = app() -> thin_builder -> select(
			Device::$table_name, 
			Device::get_fields(), 
			[ ["state", "=", "active"] ],
			[ "id" ],
			"DESC"
		);

		if(!$raw_devices) {
			return [];
		}

		// wrapped result to Device entity
		
		$devices = [];
		foreach($raw_devices as $i => $raw_device) {
			$devices[] = new Device($raw_device["id"], $raw_device);
		}

		return $devices;
	}

	public function get_unregistered_devices(): Array {
		return $this -> scanning_localnet(FCONF["device_ip_range"][0], FCONF["device_ip_range"][1], "setup");
	}

	public function scanning_localnet(String $from_ip, String $to_ip, String $status = ""): Array {
		$device_scanner = new DeviceScanner();
		$devices = $device_scanner -> scan_range($from_ip, $to_ip);
		if(!$status) {
			return $devices;
		}

		return $device_scanner -> filter_by_status($devices, $status);
	}
}