# Path: conf/ConfigWrapper.py
# class ConfigWrapper:
#     """
#     Used for loading and accessing values from a json config file.
#     """
#     def __init__(self, d: Dict):
#         self.d = d
# 
#     @staticmethod
#     def new(filename: str):
#         with open(filename) as confFile:
#             return ConfigWrapper(json.load(confFile))
# 
#     def __getitem__(self, key: str):
#         """
#         allows for accessing like, conf["index items like this"]
#         """
#         try:
#             head, tail = key.split(' ', 1)
#             return self.__getattr__(head)[tail]
#         except ValueError:
#             return self.__getattr__(key)
# 
#     def __getattr__(self, key: str):
#         """
#         allows for accessing like, conf.index.like.this
#         """
#         r = self.d.get(key)
#         if isinstance(r, dict):
#             return ConfigWrapper(r)
#         return r
# 
#     def asdict(self) -> Dict:
#         return self.d
# 
#     def __repr__(self):
#         return "ConfigWrapper({})".format(self.d)
# 
# Path: webapp/Env.py
# class Env:
#     def __init__(self, config):
#         self.config = config
# 
#         ## Database
#         self.dbManager = DBManager(self.config)
#         self.db = self.dbManager.db()
# 
#         ## Envs
#         self.authEnv = AuthEnv(self.config, self.db)
#         self.gameEnv = GameEnv(self.config, self.db)
#         self.queueEnv = QueueEnv(self.config, self.db)
#         self.irwinEnv = IrwinEnv(self.config, self.db)
# 
#         ## Modules
#         self.auth = Auth(self.authEnv)
#         self.gameApi = GameApi(self.gameEnv)
#         self.queue = Queue(self.queueEnv)
#         self.irwin = Irwin(self.irwinEnv)
#         self.lichessApi = LichessApi(self.config['api url'], self.config['api token'])
# 
# Path: modules/db/DBManager.py
# class DBManager(NamedTuple('DBManager', [
#         ('config', 'ConfigWrapper')
#     ])):
#     def client(self) -> MongoClient:
#         return MongoClient(self.config.db.host)
# 
#     def db(self) -> Database:
#         client = self.client()
#         db = client[self.config['db database']]
#         if self.config['db authenticate']:
#             db.authenticate(
#                 self.config.authentication.username,
#                 self.config.authentication.password, mechanism='MONGODB-CR')
#         return db
# 
# Path: webapp/controllers/api/blueprint.py
# def buildApiBlueprint(env):
#     apiBlueprint = Blueprint('Api', __name__, url_prefix='/api')
# 
#     @apiBlueprint.route('/request_job', methods=['GET'])
#     @env.auth.authoriseRoute(RequestJob)
#     def apiRequestJob(authable):
#         engineQueue = env.queue.nextEngineAnalysis(authable.id)
#         logging.debug(f'EngineQueue for req {engineQueue}')
#         if engineQueue is not None:
#             requiredGames = env.gameApi.gamesForAnalysis(engineQueue.id, engineQueue.requiredGameIds)
#             requiredGameIds = [g.id for g in requiredGames]
# 
#             logging.warning(f'Requesting {authable.name} analyses {requiredGameIds} for {engineQueue.id}')
# 
#             job = Job(
#                 playerId = engineQueue.id,
#                 games = requiredGames,
#                 analysedPositions = [])
# 
#             logging.info(f'Job: {job}')
# 
#             return  Response(
#                 response = json.dumps(job.toJson()),
#                 status = 200,
#                 mimetype = 'application/json')
#         return NotAvailable
# 
#     @apiBlueprint.route('/complete_job', methods=['POST'])
#     @env.auth.authoriseRoute(CompleteJob)
#     def apiCompleteJob(authable):
#         req = request.get_json(silent=True)
#         try:
#             job = Job.fromJson(req['job'])
#             insertRes = env.gameApi.writeAnalysedGames(req['analysedGames'])
#             if insertRes:
#                 env.queue.completeEngineAnalysis(job.playerId)
# 
#                 player = env.irwin.env.playerDB.byId(job.playerId)
#                 analysedGames = env.irwin.env.analysedGameDB.byPlayerId(job.playerId)
#                 games = env.irwin.env.gameDB.byIds([ag.gameId for ag in analysedGames])
#                 predictions = env.irwin.analysedGameModel.predict([GameAnalysedGame(ag, g) for ag, g in zip(analysedGames, games) if ag.gameLength() <= 60])
# 
#                 playerReport = PlayerReport.new(player, zip(analysedGames, predictions), owner = authable.name)
#                 logging.warning(f'Sending player report for {playerReport.playerId}, activation {playerReport.activation}%')
#                 env.lichessApi.postReport(playerReport)
# 
#                 return Success
#         except KeyError as e:
#             tb = traceback.format_exc()
#             logging.warning(f'Error completing job: {tb}')
# 
#         return BadRequest
# 
#     return apiBlueprint


from default_imports import *
from conf.ConfigWrapper import ConfigWrapper
from webapp.Env import Env
from modules.db.DBManager import DBManager
from flask import Flask
from webapp.controllers.api.blueprint import buildApiBlueprint
import sys








config = ConfigWrapper.new('conf/server_config.json')

loglevels = {
    'CRITICAL': logging.CRITICAL,
    'ERROR': logging.ERROR,
    'WARNING': logging.WARNING,
    'INFO': logging.INFO,
    'DEBUG': logging.DEBUG,

# Path: conf/ConfigWrapper.py
# class ConfigWrapper:
#     """
#     Used for loading and accessing values from a json config file.
#     """
#     def __init__(self, d: Dict):
#         self.d = d
# 
#     @staticmethod
#     def new(filename: str):
#         with open(filename) as confFile:
#             return ConfigWrapper(json.load(confFile))
# 
#     def __getitem__(self, key: str):
#         """
#         allows for accessing like, conf["index items like this"]
#         """
#         try:
#             head, tail = key.split(' ', 1)
#             return self.__getattr__(head)[tail]
#         except ValueError:
#             return self.__getattr__(key)
# 
#     def __getattr__(self, key: str):
#         """
#         allows for accessing like, conf.index.like.this
#         """
#         r = self.d.get(key)
#         if isinstance(r, dict):
#             return ConfigWrapper(r)
#         return r
# 
#     def asdict(self) -> Dict:
#         return self.d
# 
#     def __repr__(self):
#         return "ConfigWrapper({})".format(self.d)
# 
# Path: webapp/Env.py
# class Env:
#     def __init__(self, config):
#         self.config = config
# 
#         ## Database
#         self.dbManager = DBManager(self.config)
#         self.db = self.dbManager.db()
# 
#         ## Envs
#         self.authEnv = AuthEnv(self.config, self.db)
#         self.gameEnv = GameEnv(self.config, self.db)
#         self.queueEnv = QueueEnv(self.config, self.db)
#         self.irwinEnv = IrwinEnv(self.config, self.db)
# 
#         ## Modules
#         self.auth = Auth(self.authEnv)
#         self.gameApi = GameApi(self.gameEnv)
#         self.queue = Queue(self.queueEnv)
#         self.irwin = Irwin(self.irwinEnv)
#         self.lichessApi = LichessApi(self.config['api url'], self.config['api token'])
# 
# Path: modules/db/DBManager.py
# class DBManager(NamedTuple('DBManager', [
#         ('config', 'ConfigWrapper')
#     ])):
#     def client(self) -> MongoClient:
#         return MongoClient(self.config.db.host)
# 
#     def db(self) -> Database:
#         client = self.client()
#         db = client[self.config['db database']]
#         if self.config['db authenticate']:
#             db.authenticate(
#                 self.config.authentication.username,
#                 self.config.authentication.password, mechanism='MONGODB-CR')
#         return db
# 
# Path: webapp/controllers/api/blueprint.py
# def buildApiBlueprint(env):
#     apiBlueprint = Blueprint('Api', __name__, url_prefix='/api')
# 
#     @apiBlueprint.route('/request_job', methods=['GET'])
#     @env.auth.authoriseRoute(RequestJob)
#     def apiRequestJob(authable):
#         engineQueue = env.queue.nextEngineAnalysis(authable.id)
#         logging.debug(f'EngineQueue for req {engineQueue}')
#         if engineQueue is not None:
#             requiredGames = env.gameApi.gamesForAnalysis(engineQueue.id, engineQueue.requiredGameIds)
#             requiredGameIds = [g.id for g in requiredGames]
# 
#             logging.warning(f'Requesting {authable.name} analyses {requiredGameIds} for {engineQueue.id}')
# 
#             job = Job(
#                 playerId = engineQueue.id,
#                 games = requiredGames,
#                 analysedPositions = [])
# 
#             logging.info(f'Job: {job}')
# 
#             return  Response(
#                 response = json.dumps(job.toJson()),
#                 status = 200,
#                 mimetype = 'application/json')
#         return NotAvailable
# 
#     @apiBlueprint.route('/complete_job', methods=['POST'])
#     @env.auth.authoriseRoute(CompleteJob)
#     def apiCompleteJob(authable):
#         req = request.get_json(silent=True)
#         try:
#             job = Job.fromJson(req['job'])
#             insertRes = env.gameApi.writeAnalysedGames(req['analysedGames'])
#             if insertRes:
#                 env.queue.completeEngineAnalysis(job.playerId)
# 
#                 player = env.irwin.env.playerDB.byId(job.playerId)
#                 analysedGames = env.irwin.env.analysedGameDB.byPlayerId(job.playerId)
#                 games = env.irwin.env.gameDB.byIds([ag.gameId for ag in analysedGames])
#                 predictions = env.irwin.analysedGameModel.predict([GameAnalysedGame(ag, g) for ag, g in zip(analysedGames, games) if ag.gameLength() <= 60])
# 
#                 playerReport = PlayerReport.new(player, zip(analysedGames, predictions), owner = authable.name)
#                 logging.warning(f'Sending player report for {playerReport.playerId}, activation {playerReport.activation}%')
#                 env.lichessApi.postReport(playerReport)
# 
#                 return Success
#         except KeyError as e:
#             tb = traceback.format_exc()
#             logging.warning(f'Error completing job: {tb}')
# 
#         return BadRequest
# 
#     return apiBlueprint


# Path: app.py
from default_imports import *
from conf.ConfigWrapper import ConfigWrapper
from webapp.Env import Env
from modules.db.DBManager import DBManager
from flask import Flask
from webapp.controllers.api.blueprint import buildApiBlueprint
import sys









config = ConfigWrapper.new('conf/server_config.json')

loglevels = {
    'CRITICAL': logging.CRITICAL,
    'ERROR': logging.ERROR,
    'WARNING': logging.WARNING,
    'INFO': logging.INFO,
    'DEBUG': logging.DEBUG,

    'NOTSET': logging.NOTSET