# coding: utf-8

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import json
import logging

from library.python import resource

from saas.library.python.nanny_rest.tickets_integration.enums import ReleaseType, TicketPriority
from saas.library.python.nanny_rest.tickets_integration.autocommit_settings import AutocommitSettings


class TicketsIntegrationRule(object):
    LOGGER = logging.getLogger(__name__)
    optional_fields = ('sandbox_task_type', 'sandbox_resource_type')

    default_approve_policy = json.loads(resource.find('saas/library/nanny/approve_policy_template.json'))
    default_responsibles = [{'login': 'saas-robot', 'email': 'saas-robot@yandex-team.ru'}]

    repr_args_str = (
        '{desc}, {filter_params}, {sandbox_task_type}, {sandbox_resource_type}, ticket_priority={ticket_priority}, '
        'responsibles={responsibles}, approve_policy={approve_policy}, auto_commit_settings={auto_commit_settings}',
        '{extra}'
    )
    repr_str = 'TicketsIntegrationRule({})'.format(repr_args_str)

    def __init__(
        self, desc, filter_params, sandbox_task_type=None, sandbox_resource_type=None,
        ticket_priority=TicketPriority.normal, responsibles=None, approve_policy=None, auto_commit_settings=None,
        **kwargs
    ):
        if not desc:
            raise ValueError('Description required to be not empty')
        self.description = desc
        self.sandbox_task_type = sandbox_task_type
        self.sandbox_resource_type = sandbox_resource_type
        self.responsibles = responsibles if responsibles else []
        self.approve_policy = approve_policy if approve_policy else self.default_approve_policy
        self.filter_expression = filter_params['expression'] if isinstance(filter_params, dict) else filter_params
        self.ticket_priority = ticket_priority if isinstance(ticket_priority, TicketPriority) else TicketPriority(ticket_priority)

        if auto_commit_settings is None or isinstance(auto_commit_settings, AutocommitSettings):
            self.autocommit = auto_commit_settings
        else:
            self.autocommit = AutocommitSettings(**auto_commit_settings)

        self.extra_params = kwargs
        if 'filter_params' in self.extra_params:
            self.LOGGER.error('filter_params not supported for TicketsIntegrationRule use filter_expression')
            raise ValueError('filter_params not supported for TicketsIntegrationRule use filter_expression')

    def dict(self):
        base_dict = {
            'desc': self.description,
            'ticket_priority': self.ticket_priority.value,
            'filter_params': {'expression': self.filter_expression},
            'approve_policy': self.approve_policy,
            'responsibles': self.responsibles,
        }
        for optional_field in self.optional_fields:
            if getattr(self, optional_field):
                base_dict[optional_field] = getattr(self, optional_field)

        if self.autocommit and self.autocommit.enabled:
            base_dict['auto_commit_settings'] = self.autocommit.dict()

        base_dict.update(self.extra_params)

        return base_dict

    def __str__(self):
        return json.dumps(self.dict())

    def __repr__(self):
        return self.repr_str.format(
            desc=self.description, filter_params=self.filter_expression, sandbox_task_type=self.sandbox_task_type,
            sandbox_resource_type=(self.sandbox_resource_type or 'None'), ticket_priority=self.ticket_priority,
            responsibles=(self.responsibles or 'None'), approve_policy=self.approve_policy,
            auto_commit_settings=self.autocommit,
            extra=','.join('{}={}'.format(k, v) for k, v in self.extra_params.items())
        )

    def __hash__(self):
        return hash(self.sandbox_task_type)

    def __eq__(self, other):
        return (self.sandbox_task_type == other.sandbox_task_type and
                self.sandbox_resource_type == other.sandbox_resource_type and
                self.filter_expression == other.filter_expression and
                self.autocommit == other.autocommit)


class SimpleTicketIntegrationRule(TicketsIntegrationRule):
    def __init__(self, sandbox_task_type, sandbox_resource_type,
                 desc, release_types=(ReleaseType.stable,), **kwargs):
        if not sandbox_task_type:
            raise ValueError('sandbox_task_type must be set for SimpleTicketIntegrationRule, but got "{}"'.format(
                sandbox_task_type))
        if isinstance(release_types, ReleaseType):
            release_types = [release_types, ]
        str_release_types = set(['"{}"'.format(release_type.value) for release_type in release_types])
        filter_expression = 'sandbox_release.release_type in ({})'.format(','.join(str_release_types))

        if 'filter_expression' in kwargs:
            self.LOGGER.error('Explict filter_expression not supported in SimpleTicketIntegrationRule')
            del kwargs['filter_expression']

        super(SimpleTicketIntegrationRule, self).__init__(
            desc, filter_expression, sandbox_task_type, sandbox_resource_type, **kwargs
        )
