# coding: utf8

import sqlalchemy as sa

from yandex.maps.wiki.utils import require
from yandex.maps.wiki import db, fastcgihelpers as fh
from yandex.maps.wiki import pgpool3
from yandex.maps.wiki import config
from yandex.maps.wiki.tasks import EM
from yandex.maps.wiki.tasks import register_task_type
from yandex.maps.wiki.tasks import grinder
from yandex.maps.wiki.tasks.models import Task, Base

from maps.wikimap.mapspro.libs.python import acl
from maps.wikimap.mapspro.libs.python.social import feedback

TASK_NAME = 'validation_feedback_converter'

ACL_PATH = 'mpro/tasks/validation-feedback-converter'

SEVERITY_DICT = {
    'warn': 0,
    'error': 1,
    'crit': 2,
    'fatal': 3
}

IMPORTANT_REGION_DICT = {
    'unimportant': False,
    'important': True
}


@register_task_type(name=TASK_NAME)
class ValidationFeedbackConverter:
    @staticmethod
    def capabilities_ET():
        return EM.validation_feedback_converter_task_type()

    @staticmethod
    def create(uid, request):
        require(
            acl.is_permission_granted(pgpool3.get_pgpool(db.CORE_DB), ACL_PATH, uid, None),
            fh.ServiceException('forbidden', status='ERR_FORBIDDEN')
        )

        require(
            'validation-task-id' in request.values,
            fh.ServiceException('param validation-task-id required', status='ERR_BAD_REQUEST')
        )

        task = ValidationFeedbackConverterTask()
        task.on_create(uid)
        task.validation_task_id = request.values['validation-task-id']

        if 'severity' in request.values:
            require(
                request.values['severity'] in SEVERITY_DICT,
                fh.ServiceException('severity {0!r} is not supported'.format(request.values['severity']), status='ERR_BAD_REQUEST')
            )
            task.severity = SEVERITY_DICT[request.values['severity']]

        if 'check' in request.values:
            require(
                request.values['check'] in feedback.validation_feedback_converter_checks(),
                fh.ServiceException('check {0!r} is not supported'.format(request.values['check']), status='ERR_BAD_REQUEST')
            )
            task.check_id = request.values['check']

        if 'description' in request.values:
            require(
                request.values['description'] in feedback.validation_feedback_converter_descriptions(),
                fh.ServiceException('description {0!r} is not supported'.format(request.values['description']), status='ERR_BAD_REQUEST')
            )
            task.description = request.values['description']

        if 'region-type' in request.values:
            require(
                request.values['region-type'] in IMPORTANT_REGION_DICT,
                fh.ServiceException('region type {0!r} is not supported'.format(request.values['region-type']), status='ERR_BAD_REQUEST')
            )
            task.important_region = IMPORTANT_REGION_DICT[request.values['region-type']]

        return task

    @staticmethod
    def launch(session, task_id, request):
        task = session.query(ValidationFeedbackConverterTask).get(task_id)
        args = {
            'type': TASK_NAME,
            'taskId': task_id,
            'validationTaskId': task.validation_task_id,
        }
        if task.severity:
            args['severity'] = task.severity
        if task.check_id:
            args['checkId'] = task.check_id
        if task.description:
            args['description'] = task.description
        if task.important_region:
            args['importantRegion'] = task.important_region
        gateway = grinder.GrinderGateway(config.get_config().grinder_params.host)
        return gateway.submit(args)


class ValidationFeedbackConverterResult(Base):
    __tablename__ = 'validation_feedback_converter_result'
    __table_args__ = (
        sa.PrimaryKeyConstraint('task_id'),
        {'schema': 'service'}
    )

    task_id = sa.Column(sa.BigInteger,
                        sa.ForeignKey('service.validation_feedback_converter_task.id'))
    created_tasks_count = sa.Column(sa.BigInteger)


class ValidationFeedbackConverterTask(Task):
    __mapper_args__ = {'polymorphic_identity': TASK_NAME}
    __tablename__ = 'validation_feedback_converter_task'
    __table_args__ = {'schema': 'service'}

    id = sa.Column(sa.BigInteger,
                   sa.ForeignKey('service.task.id'),
                   primary_key=True)
    validation_task_id = sa.Column(sa.BigInteger, nullable=False)
    severity = sa.Column(sa.INT)
    check_id = sa.Column(sa.Text)
    description = sa.Column(sa.Text)
    important_region = sa.Column(sa.Boolean)

    def __result_ET(self):
        ret = EM.validation_feedback_converter_result()
        session = sa.orm.session.Session.object_session(self)
        for r in session.query(ValidationFeedbackConverterResult).filter_by(task_id=self.id):
            ret.append(EM.created_tasks_count(r.created_tasks_count))
        return ret

    def __context_ET(self):
        ivc_args = [EM.validation_task_id(self.validation_task_id), ]
        if self.check_id:
            ivc_args.append(EM.check_id(self.check_id))
        if self.important_region:
            ivc_args.append(EM.important_region(self.important_region))
        if self.severity:
            ivc_args.append(EM.severity(self.severity))
        if self.description:
            ivc_args.append(EM.description(self.description))
        return EM.import_validation_context(*ivc_args)

    def context_ET_brief(self, *args, **kwargs):
        return self.__context_ET()

    def context_ET_full(self, *args, **kwargs):
        return self.__context_ET()

    def result_ET_full(self, page=1, per_page=10, *args, **kwargs):
        return self.__result_ET()

    def result_ET_brief(self, page=1, per_page=10, *args, **kwargs):
        return self.__result_ET()
