from flask import make_response, request, abort
from flask.views import View

from pycs.database.Database import Database
from pycs.frontend.endpoints.pipelines.PredictModel import PredictModel as Predict
from pycs.frontend.notifications.NotificationList import NotificationList
from pycs.frontend.notifications.NotificationManager import NotificationManager
from pycs.jobs.JobGroupBusyException import JobGroupBusyException
from pycs.jobs.JobRunner import JobRunner
from pycs.util.PipelineCache import PipelineCache


class PredictFile(View):
    """
    load a model and create predictions or a given file
    """
    # pylint: disable=arguments-differ
    methods = ['POST']

    def __init__(self,
                 db: Database, nm: NotificationManager, jobs: JobRunner, pipelines: PipelineCache):
        # pylint: disable=invalid-name
        self.db = db
        self.nm = nm
        self.jobs = jobs
        self.pipelines = pipelines

    def dispatch_request(self, file_id):
        # extract request data
        data = request.get_json(force=True)

        if 'predict' not in data or data['predict'] is not True:
            return abort(400)

        # find file
        file = self.db.file(file_id)
        if file is None:
            return abort(404)

        # get project and model
        project = file.project()

        # create job
        try:
            notifications = NotificationList(self.nm)

            self.jobs.run(project,
                          'Model Interaction',
                          f'{project.name} (create predictions)',
                          f'{project.name}/model-interaction',
                          Predict.load_and_predict,
                          self.db, self.pipelines, notifications, project.identifier, [file],
                          progress=Predict.progress)
        except JobGroupBusyException:
            return abort(400)

        return make_response()
