<?php

class Device {

    public static function checkIceBearAvailable(): array {
        return [
            'isAvailable'=>true
        ];
    }

	/**
	 * @param array|string $parameterNames
	 * @param array $parameters
	 * @throws BadRequestException
	 */
    public static function require(array|string $parameterNames, array $parameters): void {
        if(!is_array($parameterNames)){
            $parameterNames=[$parameterNames];
        }
        foreach ($parameterNames as $parameterName) {
            if(!isset($parameters[$parameterName])){
                throw new BadRequestException(get_called_class().': Parameter '.$parameterName.' is required');
            }
        }
    }

/**
 * @param $parameterNames array An array of parameter names
 * @param $parameters array The parameters to be checked
 * @throws BadRequestException
 */
    public static function requireOneOf(array $parameterNames, array $parameters): bool {
        foreach($parameterNames as $parameterName){
            if(isset($parameters[$parameterName])){
                return true;
            }
        }
        throw new BadRequestException(get_called_class().': At least one of ['.implode(',',$parameterNames).'] is required');
    }

    //Override these with a device-specific name
    const USERNAME='device_api';
    const USERFULLNAME='Device API';

    public static function getUsername(): string {
        return static::USERNAME;
    }

    public static function getUserFullName(): string {
        return static::USERFULLNAME;
    }

    /**
     * @throws ServerException
     * @throws NotFoundException
     * @throws BadRequestException
     */
    public static function getSharedProjectId(): int {
        $project=project::getByName(baseproject::SHARED);
		if(!$project){
			throw new NotFoundException('Could not read shared project.');
		}
        return $project['id'];
    }

    /**
     * @throws ServerException
     * @throws NotFoundException
     * @throws BadRequestException
     */
    public static function getDefaultProjectId(): int {
        $project=project::getByName(baseproject::DEFAULTPROJECT);
		if(!$project){
			throw new NotFoundException('Could not read default project.');
		}
        return $project['id'];
    }

    /**
     * @throws ForbiddenException
     * @throws BadRequestException
     * @throws ServerException
     * @throws NotFoundException
     */
    public static function setScopeUserToSession(string $scope=null): void {
		if(!$scope){
			$scope=get_called_class();
		}
        $username=forward_static_call_array(array($scope, 'getUsername'), array());
        session::becomeAdmin();
        $user=user::getByName($username);
        if(!$user) {
            try {
                $password=bin2hex(random_bytes(10));
            } catch (Exception){
                throw new ServerException('Failed to create IceBear user for this scope. PHP random_bytes() threw an exception.');
            }
            $userFullName=forward_static_call_array(array($scope, 'getUserFullName'), array());
            user::create(array(
                'name'=>$username,
                'fullname'=>$userFullName,
                'email'=>$username.'@bogus.example.com',
                'password'=>$password,
                'isactive'=>false
            ));
            $user=user::getByName($username);
        }
        $userId=$user['id'];
        session::set('user', $user);
        session::set('userId',$userId);
        session::refreshProjectPermissions();
    }

	/**
	 * @param array $params
	 * @return array[]
	 * @throws BadRequestException
	 * @throws ServerException
	 */
    public static function updateDiskSpaces(array $params): array {
        static::require('drives', $params);
        session::becomeAdmin();
        $updatedDrives = [];
        foreach ($params['drives'] as $deviceDrive) {
            static::require(['bytesused','bytesfree','machine','label'], $deviceDrive);
            $drive=array();
            $used=1*$deviceDrive['bytesused'];
            $free=1*$deviceDrive['bytesfree'];
            $size=$used+$free;
            $drive['used']=diskusage::bytesToFriendlyString($used);
            $drive['free']=diskusage::bytesToFriendlyString($free);
            $drive['size']=diskusage::bytesToFriendlyString($size);
            $drive['percent']=round(100*$used/$size);
            $drive['mountpoint']=$deviceDrive['machine'].' '. $deviceDrive['label']; //"RockMaker C:"
            if(!empty($deviceDrive['mappedto'])){
                $drive['filesystem']=$deviceDrive['mappedto'];
            } else {
                $drive['filesystem']=$deviceDrive['label'];
            }
            $updatedDrives[]=$drive;
        }
        return array('updatedDrives' => $updatedDrives);
    }

}