from flask import abort
from flask import jsonify
from flask import request
from flask.views import View

from pycs import db
from pycs.database.File import File
from pycs.frontend.notifications.NotificationManager import NotificationManager


class CreateResult(View):
    """
    create a result for a file
    """
    # pylint: disable=arguments-differ
    methods = ['POST']

    def __init__(self, nm: NotificationManager):
        # pylint: disable=invalid-name
        self.nm = nm

    @staticmethod
    def extract_request_data():
        """ get the data from the request and validate it """
        request_data = request.get_json(force=True)

        if 'type' not in request_data:
            abort(400, "result type argument is missing")

        result_type = request_data.get('type')
        if result_type not in ['labeled-image', 'bounding-box']:
            abort(400, "result type must be either 'labeled-image' or 'bounding-box'")

        label = None
        data = None

        if result_type == 'labeled-image':
            label = request_data.get('label')
            if label is None:
                abort(400, f"Could not find label argument ({result_type=})")

        elif result_type == 'bounding-box':
            data = request_data.get('data')
            if data is None:
                abort(400, f"Could not find data argument ({result_type=})")

        return result_type, label, data


    def dispatch_request(self, file_id: int):

        file = File.get_or_404(file_id)

        result_type, label, data = self.extract_request_data()


        # start transaction
        with db.session.begin_nested():
            # find full-image labels and remove them
            image_results = file.results.filter_by(type='labeled-image')

            removed = [result.serialize() for result in image_results.all()]
            image_results.delete()

            for result in removed:
                self.nm.remove_result(result)

            # insert into database
            result = file.create_result(
                origin='user',
                result_type=result_type,
                label=label,
                data=data)

            self.nm.create_result(result)

        return jsonify(result)
