# -*- coding: utf-8 -*-

# Copyright (C) 2016 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>


from sqlalchemy import or_, and_
from sqlalchemy.sql.functions import ReturnTypeFromArgs
from xivo_dao.alchemy import UserFeatures
from xivo_dao.alchemy.meetingroom import MeetingRoom
from xivo_dao.resources.user.search import UserSearchSystemNG
from xivo_dao.resources.utils.searchers import SearcherCombinedNG, SearcherFuzzy


class unaccent(ReturnTypeFromArgs):
    pass


STATIC = 'static'
PERSONAL = 'personal'


def get_configuration():
    configuration = {
        'table': MeetingRoom,
        'columns': {
            'id': MeetingRoom.id,
            'uuid': UserFeatures.uuid,
            'display_name': MeetingRoom.display_name,
            'number': MeetingRoom.number,
            'room_type': MeetingRoom.room_type
        },
        'search': [
            'display_name'
        ],
        'default_sort': 'display_name',
        'similarity_threshold': 0.1,
        'unique_column': 'id'
    }
    return configuration


class MeetingroomFilters(object):
    def _room_filter(self, parameters):
        uuid = parameters.get('user_uuid')
        room_filter = self.config.table.room_type == STATIC
        if uuid:
            room_filter = or_(
                room_filter,
                and_(
                    self.config.table.room_type == PERSONAL,
                    UserFeatures.uuid == uuid
                )
            )
        return room_filter


class MeetingroomSearcherCombined(SearcherCombinedNG, MeetingroomFilters):

    def _filter(self, query, parameters):
        room_filter = self._room_filter(parameters)
        term_filter = self._term_filter(parameters)
        final_filter = and_(room_filter, term_filter) if term_filter is not None else room_filter
        return query.filter(final_filter)


class MeetingroomSearcherFuzzy(SearcherFuzzy, MeetingroomFilters):

    def _filter(self, query, parameters):
        similarity_threshold = self.config.similarity_threshold
        return query.filter(
            and_(
                self._room_filter(parameters),
                or_(*[_ > similarity_threshold for _ in self._similarities()])
            )
        )

    pass


class MeetingroomSearchSystem(UserSearchSystemNG):
    searchers = (MeetingroomSearcherCombined, MeetingroomSearcherFuzzy)

    @staticmethod
    def search_on_extension(query):
        return query.outerjoin(UserFeatures, UserFeatures.id == MeetingRoom.user_id)
