# -*- coding: utf-8 -*-
from plone import api
from Products.CMFCore.interfaces import IFolderish
from Products.CMFPlone.utils import safe_unicode
import six
from plone.app.contenttypes.behaviors.collection import ISyndicatableCollection
from plone.uuid.interfaces import IUUID
from zope.interface import provider
from zope.schema.interfaces import IContextAwareDefaultFactory


def target_collection_base_path(context):
    for potential_context in context.aq_chain:
        if (IFolderish.providedBy(potential_context)):
            # Actually makes no sense to pick the collection path as it means you have to go up
            # to pick teh collection. Instead the collection should be the default
            #    or
            # ISyndicatableCollection.providedBy(potential_context
            #                                   )
            context = potential_context
            break
    return '/'.join(context.getPhysicalPath())


def target_collection_types(context):
    return api.portal.get_registry_record(
        'collective.collectionfilter.target_collection_types',
        default=['Collection', ])


@provider(IContextAwareDefaultFactory)
def target_collection_default(context):
    for potential_context in context.aq_chain:
        if ISyndicatableCollection.providedBy(potential_context):
            return IUUID(potential_context, None)
    return None


def safe_decode(val):
    """Safely create unicode values.
    """
    ret = val
    if isinstance(val, dict):
        ret = dict([(safe_decode(k), safe_decode(v)) for k, v in val.items() if v is not None])  # noqa
    elif isinstance(val, list):
        ret = [safe_decode(it) for it in val]
    elif isinstance(val, tuple):
        ret = (safe_decode(it) for it in val)
    elif val:
        ret = safe_unicode(val)
    return ret


def safe_encode(val):
    """Safely encode a value to utf-8.
    """
    ret = val
    if isinstance(val, dict):
        ret = dict([(safe_encode(k), safe_encode(v)) for k, v in val.items() if v is not None])  # noqa
    elif isinstance(val, list):
        ret = [safe_encode(it) for it in val]
    elif isinstance(val, tuple):
        ret = (safe_encode(it) for it in val)
    elif isinstance(val, six.string_types):
        ret = safe_unicode(val).encode('utf-8')
    return ret


def safe_iterable(value):
    if value is None:
        return []
    if isinstance(value, six.string_types):
        # do not expand a string to a list of chars
        return [value, ]
    else:
        try:
            return list(value)
        except TypeError:
            # int and other stuff
            return [value, ]
    # could not convert
    return []


def base_query(request_params={}, extra_ignores=[]):
    """Construct base url query.
    """

    # Defaults
    request_params = request_params or {}
    extra_ignores = extra_ignores or []

    # These request params should be ignored.
    ignore_params = [
        'b_start',
        'b_size',
        'batch',
        'sort_on',
        'limit',
        'portlethash',
    ] + extra_ignores
    # Now remove all to-be-ignored request parameters.
    urlquery = {
        k: v for k, v in list(request_params.items()) if k not in ignore_params
    }
    urlquery.update({'collectionfilter': '1'})  # marker
    return urlquery


def get_top_request(request):
    """Get highest request from a subrequest.
    """

    def _top_request(req):
        parent_request = req.get('PARENT_REQUEST', None)
        return _top_request(parent_request) if parent_request else req
    return _top_request(request)
