# Path: modules/auth/Auth.py
# class Auth(NamedTuple('Auth', [('env', Env)])):
#     def loginUser(self, username: Username, password: Password) -> Tuple[Opt[User], Authorised]:
#     def registerUser(self, name: Username, password: Password, privs: List[Priv] = []) -> Opt[User]:
#     def authoriseTokenId(self, tokenId: TokenID, priv: Priv) -> Tuple[Opt[Token], Authorised]:
#     def authoriseUser(self, username: Username, password: Password, priv: Priv) -> Tuple[Opt[User], Authorised]:
#     def authoriseRequest(self, req: Opt[Dict], priv: Priv) -> Tuple[Opt[Authable], Authorised]:
#     def authoriseRoute(self, priv: Priv):
#         def decorator(func):
#             def wrapper(*args, **kwargs):
# 
# Path: modules/game/Game.py
# class Game(NamedTuple('Game', [
#         ('id', GameID),
#         ('white', PlayerID),
#         ('black', PlayerID),
#         ('pgn', List[str]),
#         ('emts', Opt[List[Emt]]),
#         ('analysis', Analysis)
#     ])):
# class GameBSONHandler:
# class GameDB(NamedTuple('GameDB', [
#         ('gameColl', Collection)
#     ])):
#     def fromDict(d: Dict):
#     def fromJson(json: Dict):
#     def toJson(self):
#     def playable(self):
#     def boardTensors(self, colour):
#     def boardTensorsByPlayerId(self, playerId: PlayerID, length: int = 60, safe: bool = True):
#     def tensor(self, playerId: PlayerID, length: int = 60, noisey: bool = False, safe: bool = True) -> Opt[GameTensor]:
#     def emtsByColour(self, colour: Colour, emts: Opt[List[int]] = None) -> List[Emt]:
#     def moveTensor(analysis: Analysis, emt: Emt, boardTensor: List[int], avgEmt: Number, colour: Colour) -> MoveTensor:
#     def nullBoardTensor():
#     def nullMoveTensor() -> MoveTensor:
#     def ply(moveNumber: int, colour: Colour) -> int:
#     def reads(bson: Dict) -> Game:
#     def writes(game: Game) -> Dict:
#     def byId(self, _id: GameID) -> Opt[Game]:
#     def byIds(self, ids: List[GameID]) -> List[Game]:
#     def byPlayerId(self, playerId: PlayerID) -> List[Game]:
#     def byPlayerIdAndAnalysed(self, playerId: PlayerID, analysed: bool = True) -> List[Game]:
#     def write(self, game: Game):
#     def writeMany(self, games: List[Game]):
# 
# Path: modules/queue/Origin.py
# def maxOrigin(a, b):


from default_imports import *
from modules.auth.Auth import AuthID
from modules.game.Game import Game, PlayerID, GameID
from modules.queue.Origin import Origin, OriginReport, OriginModerator, OriginRandom, maxOrigin
from datetime import datetime, timedelta
from pymongo.collection import Collection
from math import ceil
import pymongo
import numpy as np
            'date': datetime.now()
        }

class EngineQueueDB(NamedTuple('EngineQueueDB', [
        ('engineQueueColl', Collection)
    ])):
    def write(self, engineQueue: EngineQueue):
        self.engineQueueColl.update_one(
            {'_id': engineQueue.id},
            {'$set': EngineQueueBSONHandler.writes(engineQueue)}, upsert=True)

    def inProgress(self) -> List[EngineQueue]:
        return [EngineQueueBSONHandler.reads(bson) for bson in self.engineQueueColl.find({'owner': {'$ne': None}, 'completed': False})]

    def byId(self, _id: EngineQueueID) -> Opt[EngineQueue]:
        bson = self.engineQueueColl.find_one({'_id': _id})
        return None if bson is None else EngineQueueBSONHandler.reads(bson)

    def byPlayerId(self, playerId: str) -> Opt[EngineQueue]:
        return self.byId(playerId)

    def complete(self, engineQueue: EngineQueue):
        """remove a complete job from the queue"""
        self.write(engineQueue.complete())

    def updateComplete(self, _id: EngineQueueID, complete: bool):
        self.engineQueueColl.update_one(
            {'_id': _id},
            {'$set': {'completed': complete, 'owner': None}})


# Path: modules/auth/Auth.py
# class Auth(NamedTuple('Auth', [('env', Env)])):
#     def loginUser(self, username: Username, password: Password) -> Tuple[Opt[User], Authorised]:
#     def registerUser(self, name: Username, password: Password, privs: List[Priv] = []) -> Opt[User]:
#     def authoriseTokenId(self, tokenId: TokenID, priv: Priv) -> Tuple[Opt[Token], Authorised]:
#     def authoriseUser(self, username: Username, password: Password, priv: Priv) -> Tuple[Opt[User], Authorised]:
#     def authoriseRequest(self, req: Opt[Dict], priv: Priv) -> Tuple[Opt[Authable], Authorised]:
#     def authoriseRoute(self, priv: Priv):
#         def decorator(func):
#             def wrapper(*args, **kwargs):
# 
# Path: modules/game/Game.py
# class Game(NamedTuple('Game', [
#         ('id', GameID),
#         ('white', PlayerID),
#         ('black', PlayerID),
#         ('pgn', List[str]),
#         ('emts', Opt[List[Emt]]),
#         ('analysis', Analysis)
#     ])):
# class GameBSONHandler:
# class GameDB(NamedTuple('GameDB', [
#         ('gameColl', Collection)
#     ])):
#     def fromDict(d: Dict):
#     def fromJson(json: Dict):
#     def toJson(self):
#     def playable(self):
#     def boardTensors(self, colour):
#     def boardTensorsByPlayerId(self, playerId: PlayerID, length: int = 60, safe: bool = True):
#     def tensor(self, playerId: PlayerID, length: int = 60, noisey: bool = False, safe: bool = True) -> Opt[GameTensor]:
#     def emtsByColour(self, colour: Colour, emts: Opt[List[int]] = None) -> List[Emt]:
#     def moveTensor(analysis: Analysis, emt: Emt, boardTensor: List[int], avgEmt: Number, colour: Colour) -> MoveTensor:
#     def nullBoardTensor():
#     def nullMoveTensor() -> MoveTensor:
#     def ply(moveNumber: int, colour: Colour) -> int:
#     def reads(bson: Dict) -> Game:
#     def writes(game: Game) -> Dict:
#     def byId(self, _id: GameID) -> Opt[Game]:
#     def byIds(self, ids: List[GameID]) -> List[Game]:
#     def byPlayerId(self, playerId: PlayerID) -> List[Game]:
#     def byPlayerIdAndAnalysed(self, playerId: PlayerID, analysed: bool = True) -> List[Game]:
#     def write(self, game: Game):
#     def writeMany(self, games: List[Game]):
# 
# Path: modules/queue/Origin.py
# def maxOrigin(a, b):


# Path: modules/queue/EngineQueue.py
from default_imports import *
from modules.auth.Auth import AuthID
from modules.game.Game import Game, PlayerID, GameID
from modules.queue.Origin import Origin, OriginReport, OriginModerator, OriginRandom, maxOrigin
from datetime import datetime, timedelta
from pymongo.collection import Collection
from math import ceil
import pymongo
import numpy as np

            'date': datetime.now()
        }

class EngineQueueDB(NamedTuple('EngineQueueDB', [
        ('engineQueueColl', Collection)
    ])):
    def write(self, engineQueue: EngineQueue):
        self.engineQueueColl.update_one(
            {'_id': engineQueue.id},
            {'$set': EngineQueueBSONHandler.writes(engineQueue)}, upsert=True)

    def inProgress(self) -> List[EngineQueue]:
        return [EngineQueueBSONHandler.reads(bson) for bson in self.engineQueueColl.find({'owner': {'$ne': None}, 'completed': False})]

    def byId(self, _id: EngineQueueID) -> Opt[EngineQueue]:
        bson = self.engineQueueColl.find_one({'_id': _id})
        return None if bson is None else EngineQueueBSONHandler.reads(bson)

    def byPlayerId(self, playerId: str) -> Opt[EngineQueue]:
        return self.byId(playerId)

    def complete(self, engineQueue: EngineQueue):
        """remove a complete job from the queue"""
        self.write(engineQueue.complete())

    def updateComplete(self, _id: EngineQueueID, complete: bool):
        self.engineQueueColl.update_one(
            {'_id': _id},
            {'$set': {'completed': complete, 'owner': None}})


    def removePlayerId(self, playerId: PlayerID):