# -*- coding: utf-8 -*-
from plone.app.contenttypes.utils import DEFAULT_TYPES
from plone.dexterity.interfaces import IDexterityFTI
from Products.CMFCore.utils import getToolByName
from zope.component import queryUtility
from zope.component.hooks import getSite

import logging


logger = logging.getLogger(name='plone.app.contenttypes upgrade')

LISTING_VIEW_MAPPING = {  # OLD (AT and old DX) : NEW
    'all_content': 'full_view',
    'atct_album_view': 'album_view',
    'atct_topic_view': 'listing_view',
    'collection_view': 'listing_view',
    'folder_album_view': 'album_view',
    'folder_full_view': 'full_view',
    'folder_listing': 'listing_view',
    'folder_listing_view': 'listing_view',
    'folder_summary_view': 'summary_view',
    'folder_tabular_view': 'tabular_view',
    'standard_view': 'listing_view',
    'thumbnail_view': 'album_view',
    'view': 'listing_view',
}


def update_fti(context):
    """ Schema-files moved into their own folder after 1.0b1
    """
    # Document
    fti = queryUtility(
        IDexterityFTI,
        name='Document'
    )
    fti.model_file = 'plone.app.contenttypes.schema:document.xml'
    # File
    fti = queryUtility(
        IDexterityFTI,
        name='File'
    )
    fti.model_file = 'plone.app.contenttypes.schema:file.xml'
    # Folder
    fti = queryUtility(
        IDexterityFTI,
        name='Folder'
    )
    fti.model_file = 'plone.app.contenttypes.schema:folder.xml'
    # Image
    fti = queryUtility(
        IDexterityFTI,
        name='Image'
    )
    fti.model_file = 'plone.app.contenttypes.schema:image.xml'
    # Link
    fti = queryUtility(
        IDexterityFTI,
        name='Link'
    )
    fti.model_file = 'plone.app.contenttypes.schema:link.xml'
    # News Item
    fti = queryUtility(
        IDexterityFTI,
        name='News Item'
    )
    fti.model_file = 'plone.app.contenttypes.schema:news_item.xml'


def enable_collection_behavior(context):
    """Enable collection behavior on Collection."""

    fti = queryUtility(
        IDexterityFTI,
        name='Collection'
    )
    behavior = 'plone.app.contenttypes.behaviors.collection.ICollection'
    if behavior in fti.behaviors:
        return
    behaviors = list(fti.behaviors)
    behaviors.append(behavior)
    behaviors = tuple(behaviors)
    fti._updateProperty('behaviors', behaviors)


def migrate_to_richtext(context):
    """Update fti's to add RichText behaviors and remove old text-fields."""

    behavior = 'plone.app.contenttypes.behaviors.richtext.IRichText'
    types = [
        'Document',
        'News Item',
        'Event',
        'Collection',
    ]
    for type_name in types:
        fti = queryUtility(
            IDexterityFTI,
            name=type_name
        )
        if not fti:
            continue
        if behavior in fti.behaviors:
            continue
        behaviors = list(fti.behaviors)
        behaviors.append(behavior)
        fti._updateProperty('behaviors', tuple(behaviors))


def migrate_album_view(context):
    """That task is now done by use_new_view_names (1103->1104)"""
    pass


def enable_shortname_behavior(context):
    """Add IShortName to all types."""

    behavior = 'plone.app.dexterity.behaviors.id.IShortName'
    for type_id in DEFAULT_TYPES:
        fti = queryUtility(
            IDexterityFTI,
            name=type_id
        )
        if fti is None:
            continue

        if behavior in fti.behaviors:
            continue
        behaviors = list(fti.behaviors)
        behaviors.append(behavior)
        behaviors = tuple(behaviors)
        fti._updateProperty('behaviors', behaviors)


def use_new_view_names(context, types_to_fix=None):  # noqa
    """Migrate old view names to new view names."""
    # Don't reload the profile. Only change the settings.
    portal = getSite()
    portal_types = getToolByName(portal, 'portal_types')
    if types_to_fix is None:
        types_to_fix = ['Folder', 'Collection', 'Plone Site']
    outdated_methods = [
        'folder_listing',
        'folder_full_view',
        'folder_summary_view',
        'folder_tabular_view',
        'folder_album_view',
        'atct_album_view',
        'standard_view',
        'collection_view',
        'all_content',
        'thumbnail_view',
    ]
    new_methods = [
        'listing_view',
        'summary_view',
        'tabular_view',
        'full_view',
        'album_view',
        'event_listing',
    ]
    for ctype in types_to_fix:
        fti = queryUtility(IDexterityFTI, name=ctype)
        if fti is None and ctype == 'Plone Site':
            fti = portal_types.get(ctype)
        if fti is None:
            return
        view_methods = [i for i in fti.getAvailableViewMethods(None)]
        changed = False
        for method in outdated_methods:
            if method in view_methods:
                view_methods.remove(method)
                changed = True
        for method in new_methods:
            if method not in view_methods:
                view_methods.append(method)
                changed = True
        default_view = fti.default_view
        if default_view in outdated_methods:
            default_view = LISTING_VIEW_MAPPING.get(default_view)
            changed = True
        if changed:
            fti.manage_changeProperties(
                view_methods=tuple(view_methods),
                default_view=default_view,
            )
            logger.info('Updated view_methods for {0}'.format(ctype))

    def _fixup(obj, view_map):
        current = obj.getLayout()
        if current in view_map:
            default_page = obj.getDefaultPage()
            obj.setLayout(view_map[current])
            logger.info('Set view to {0} for {1}'.format(
                view_map[current],
                obj.absolute_url(),
            ))
            if default_page:
                # any defaultPage is switched of by setLayout
                # and needs to set again
                obj.setDefaultPage(default_page)

    catalog = getToolByName(portal, 'portal_catalog')
    search = catalog.unrestrictedSearchResults
    for portal_type in types_to_fix:
        for brain in search(portal_type=portal_type):
            obj = brain.getObject()
            _fixup(obj, LISTING_VIEW_MAPPING)
        if portal_type == 'Plone Site':
            _fixup(context, LISTING_VIEW_MAPPING)
