#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals, absolute_import, print_function

import json

from talos.cache.service import talos_rpc_service_model_cache
from talos.services.base import ServiceBase, RpcServiceModelCache
from talos.services.models.tag import AgileTag


class AgileTagService(ServiceBase):
    """
    新标签service
    """
    _model_name = "agile_tag_v1"  # 新加字段，原缓存失效

    __cached_layer = RpcServiceModelCache(talos_rpc_service_model_cache, _model_name)

    @classmethod
    def _filter_valid_ids(cls, ids):
        return list(filter(None, set(ids)))

    @classmethod
    def _cache_agile_tag(cls, agile_tag):
        v = agile_tag.to_json()
        cls.__cached_layer.set(agile_tag.id, v, 60 * 60)

    @classmethod
    def _get_agile_tag_from_cache_by_ids(cls, agile_tag_ids):
        cached_info = cls.__cached_layer.mget(agile_tag_ids)

        result = {}

        missing = cached_info.pop(cls.__cached_layer.missing_k)
        if missing:
            rpc_result = cls.call_rpc('api/agile_tag/info_by_ids', agile_tag_ids=missing)
            if rpc_result:
                for info in rpc_result:
                    agile_tag = AgileTag.from_dict(info)
                    if not agile_tag:
                        continue

                    result.update({
                        agile_tag.id: agile_tag
                    })
                    cls._cache_agile_tag(agile_tag)

        for k in cached_info:
            i = cached_info[k].decode()
            v = json.loads(i)
            agile_tag = AgileTag.from_dict(v)
            result.update({
                agile_tag.id: agile_tag
            })

        return result

    @classmethod
    def get_agile_tags_by_agile_tag_ids(cls, agile_tag_ids):
        """return a dict as agile_tag_id: AgileTag object."""
        agile_tag_ids = cls._filter_valid_ids(agile_tag_ids)
        return cls._get_agile_tag_from_cache_by_ids(agile_tag_ids=agile_tag_ids)

    @classmethod
    def get_agile_tags_by_agile_tag_id(cls, agile_tag_id):
        agile_tag_id = int(agile_tag_id)
        agile_tags = cls.get_agile_tags_by_agile_tag_ids(agile_tag_ids=[agile_tag_id])
        return agile_tags.get(agile_tag_id)

    @classmethod
    def get_relation_old_tags_by_agile_tag_ids(cls, agile_tag_ids):
        """
        获取新标签关联的老标签
        :param agile_tag_ids:
        :return:
        """
        result = {}
        agile_tag_ids = cls._filter_valid_ids(agile_tag_ids)

        if agile_tag_ids:
            _data = cls.call_rpc(
                "api/agile_tag/get_mapping_old_tag_ids_by_ids",
                agile_tag_ids=agile_tag_ids
            )
            for k, v in (_data.get("tag_mapping") or {}).items():
                result[int(k)] = v

        return result

    @classmethod
    def get_relation_agile_tags_by_old_tag_ids(cls, old_tag_ids):
        """
        获取老标签关联的新标签
        :param old_tag_ids:
        :return:
        """
        result = {}
        old_tag_ids = cls._filter_valid_ids(old_tag_ids)
        if old_tag_ids:
            _data = cls.call_rpc(
                "api/agile_tag/get_agile_tags_by_old_tag_ids",
                old_tag_ids=old_tag_ids
            )
            for k, v in (_data.get("tag_mapping") or {}).items():
                result[int(k)] = v

        return result
