<?php class platereimportqueue {
    const GET_BY_ID_NOT_IMPLEMENTED_ON_PLATEREIMPORTQUEUE = 'getById not implemented on platereimportqueue';
    const GET_BY_NAME_NOT_IMPLEMENTED_ON_PLATEREIMPORTQUEUE = 'getByName not implemented on platereimportqueue';
    const GET_ALL_NOT_IMPLEMENTED_ON_PLATEREIMPORTQUEUE = 'getAll not implemented on platereimportqueue';
    const PLATE_RE_IMPORT_IS_NOT_ENABLED = 'Plate re-import is not enabled';
    const PLATE_IS_ALREADY_QUEUED_FOR_RE_IMPORT = 'Plate is already queued for re-import';
    const BAD_BARCODE_PATTERN_IN_GET_OLDEST_QUEUE_ITEM = 'Bad barcode pattern in getOldestQueueItem - allowed characters ALN_-';

	public static function getFieldHelpTexts(): array {
		return [];
	}

	public static function getFieldValidations(): array {
		return [];
	}

	/**
     * @param $id
     * @throws ServerException
     * @noinspection PhpUnusedParameterInspection
     */
    public static function getById(int $id): ?array {
        throw new ServerException(self::GET_BY_ID_NOT_IMPLEMENTED_ON_PLATEREIMPORTQUEUE);
    }

    /**
     * @param $name
     * @throws ServerException
     * @noinspection PhpUnusedParameterInspection
     */
    public static function getByName(string $name): ?array {
        throw new ServerException(self::GET_BY_NAME_NOT_IMPLEMENTED_ON_PLATEREIMPORTQUEUE);
    }

    /**
     * @throws ServerException
     */
    public static function getAll(): ?array {
        throw new ServerException(self::GET_ALL_NOT_IMPLEMENTED_ON_PLATEREIMPORTQUEUE);
    }

	/**
	 * @param int $plateId
	 * @return array|bool
	 * @throws BadRequestException
	 * @throws ServerException
	 */
    public static function getByPlateId(int $plateId): ?array {
        $item=database::queryGetOne('SELECT p.ownerid AS ownerid,q.* from plate as p, platereimportqueue AS q 
            WHERE p.id=q.plateid AND q.plateid=:plateid', array(':plateid'=>$plateId));
        if(!$item){ return null; }
        if(session::isAdmin() || $item['ownerid']==session::getUserId()){ return $item; }
        return $item;
    }

	/**
	 * @param array $request
	 * @return array
	 * @throws BadRequestException
	 * @throws ForbiddenException
	 * @throws ServerException
	 */
    public static function create(array $request): array {
        if(!(int)(config::get('reimport_enabled'))){
            throw new ForbiddenException(self::PLATE_RE_IMPORT_IS_NOT_ENABLED);
        } else if(!isset($request['plateid'])){
            throw new BadRequestException('No plate ID specified');
        }
        $plate=plate::getById($request['plateid']);
        if(!$plate || !(session::isAdmin() || $plate['ownerid']==session::getUserId())){
            throw new ForbiddenException('Either the plate does not exist, or you cannot queue it for re-import');
        }
        $item=database::queryGetOne('SELECT * from platereimportqueue WHERE plateid=:plateid', array(':plateid'=>$plate['id']));
        if($item){
            throw new BadRequestException(self::PLATE_IS_ALREADY_QUEUED_FOR_RE_IMPORT);
        }
        database::query(
            'INSERT INTO platereimportqueue(plateid,queuedby,queuedtime) VALUES(:pid,:uid,:now)',
            array(
                ':pid'=>$plate['id'],
                ':uid'=>session::getUserId(),
                ':now'=>date('Y-m-d H:i:s')
            )
        );
        $newId=database::getLastInsertId();
        $newItem=database::queryGetOne('SELECT * from platereimportqueue WHERE id=:id', array(':id'=>$newId));
        return array('created'=>$newItem);
    }

	/**
	 * @param int $id
	 * @return array
	 * @throws BadRequestException
	 * @throws ForbiddenException
	 * @throws ServerException
	 */
    public static function delete(int $id): array {
        if(empty($id)){ return array(); }
        $item=database::queryGetOne('SELECT * from platereimportqueue WHERE id=:id', array(':id'=>$id));
        if(!$item){
            throw new BadRequestException('No queue item with ID '.$id);
        }
        $plate=plate::getById($item['plateid']);
        if(!$plate || !(session::isAdmin() || $plate['ownerid']==session::getUserId())){
            throw new ForbiddenException('Either the plate does not exist, or you cannot remove it from the queue');
        }
        database::query('DELETE from platereimportqueue WHERE id=:id', array(':id'=>$id));
        return array('deleted'=>$id);
    }

    /**
     * @param string $barcodePattern Describes the plate barcode format. Allowable characters L (A-Za-z), N (0-9), A (alphanumeric), _ and -.
     * @return array|null
     * @throws BadRequestException
     * @throws ServerException
     */
    public static function getOldestQueueItem(string $barcodePattern=''): ?array {
        if(!preg_match('/^[ALN_-]*$/', strtoupper($barcodePattern))){
            throw new ServerException(self::BAD_BARCODE_PATTERN_IN_GET_OLDEST_QUEUE_ITEM);
        }
        $sql='SELECT platereimportqueue.*, plate.name as barcode FROM  platereimportqueue, plate
                WHERE plate.id=platereimportqueue.plateid ';
        if(''!==$barcodePattern){
            $barcodePattern=strtoupper($barcodePattern);
            $barcodePattern=str_replace('A','[A-Za-z0-9]', $barcodePattern);
            $barcodePattern=str_replace('L','[A-Za-z]', $barcodePattern);
            $barcodePattern=str_replace('N','[0-9]', $barcodePattern);
            $sql.=' AND plate.name REGEXP "^'.$barcodePattern.'$" ';
        }
        $sql.=' ORDER BY queuedtime';
        return database::queryGetOne($sql);
    }


}