# Zope imports

# Archetypes import
from Products.Archetypes.utils import shasattr


# Product imports
from Products.CMFCore.utils import getToolByName

# test the following bibref item schema attributes to find out if the schema needs a migration
CMFBAT_SCHEMA_REMOVAL_INDICATORS = [

    'identifiers',

]

class Migration(object):
    """Migrate from 0.9 to 1.0

    It *must* be safe to use this multiple times as it is run automatically
    upon (re)install in the portal_quickinstaller.
    """

    def __init__(self, site, out):
        self.site = site
        self.out = out
        #self.catalog = getToolByName(self.site, 'portal_catalog')

    def migrate(self):
        """Run migration on site object passed to __init__.
        """
        print >> self.out
        print >> self.out, u"Migrating CMFBibliographyAT 0.9 -> 1.0"
        bibtool = getToolByName(self.site, 'portal_bibliography')
        self.migrateTool(bibtool)
        if self.needsSchemaItemRemoval():
            self.schemaItemRemoval()


    def migrateTool(self, bibtool):
        """Migrate the bibtool.
        """
        # Check for and add a persistent dictionary to keep track of
        # registered reference types on the tool.
        print >> self.out, u'BibliographyTool migration:'
        print >> self.out, u'---------------------------'
        persistent_components = ['Renderers', 'Parsers']
        REMOVED_COMPONENT = False
        for pcid in persistent_components:
            if pcid in bibtool.objectIds():
                msg = u"    Remove the persistent '%s' object." % pcid
                print >> self.out, msg
                bibtool._delObject(pcid)
                REMOVED_COMPONENT = True
        if not REMOVED_COMPONENT:
            print >> self.out, u'    Tool is up-to-date'
        print >> self.out
        
    def needsSchemaItemRemoval(self):
        """Returns True if one of the first 10 bibitems with earliest creation date found
           has missing schema fields (compared to v0.9); called
           by the installer to figure out whether a schema update
           is needed."""
        print >> self.out, u"bibliographical reference items need schema items removal"
        print >> self.out, u"---------------------------------------------------------"
        ct = getToolByName(self.site, 'portal_catalog')
        bib_tool = getToolByName(self.site, 'portal_bibliography')
        brains = ct(portal_type=bib_tool.getReferenceTypes(), Language='all', sort_on='created')

        # needs schema upgrade for authors field
        if brains:
            for attribute in CMFBAT_SCHEMA_REMOVAL_INDICATORS:
                for brain in brains[:10]:
                    if not shasattr(brain.getObject(), attribute, False):
                        return True
        print >> self.out, u"    No schema items removed."
        print >> self.out
        return False

    # migrate data from old to new schema
    def schemaItemRemoval(self):
        """perform a general AT schema upgrade"""
        ct = getToolByName(self.site, 'portal_catalog')
        bib_tool = getToolByName(self.site, 'portal_bibliography')

        # logging to ZLog and to quick installer's report
        print >> self.out, u'    Bibliographical references need schema item removal!!! This might take a while...'
        print u'***'
        print u'*** CMFBibliogaphyAT migration: Bibliographical references need general schema upgrade!!! This might take a while...'
        print u'***'
        brains = ct(portal_type=bib_tool.getReferenceTypes(), Language='all')
        for brain in brains:
            obj = brain.getObject()
            obj._updateSchema(remove_instance_schemas=True)

        print u'CMFBibliographyAT migration: Upgraded schemata of %s bibliographical references' % len(brains)
        print
        print >> self.out, u'    Upgraded schemata of %s bibliographical references' % len(brains)
        print >> self.out



