from Acquisition import aq_base
from Acquisition import aq_inner
from Acquisition import aq_parent
from euphorie.client import model
from euphorie.content.profilequestion import ProfileQuestion
from plone.dexterity.utils import createContent
from Products.CMFCore.utils import getToolByName
from sqlalchemy.engine.reflection import Inspector
from z3c.saconfig import Session
from zope.sqlalchemy import datamanager

import collections
import datetime
import logging


log = logging.getLogger(__name__)


def _convert_to_module(question):
    log.info("Converting %s to module", "/".join(question.getPhysicalPath()))
    parent = aq_parent(question)
    question = aq_base(question)
    module = createContent("euphorie.module")
    module.id = question.id
    module.creation_date = question.creation_date
    module.modification_date = question.modification_date
    module.creators = question.creators
    if getattr(question, "external_id", None):
        module.external_id = question.external_id
    module.title = question.title
    module.question = question.question
    module.description = question.description
    module.optional = True
    children = question.getOrdering().idsInOrder()
    for key in children:
        module._setObject(key, question[key], suppress_events=True)
    ordering = parent.getOrdering()
    position = ordering.getObjectPosition(question.id)
    parent._delOb(question.id)
    parent._setObject(question.id, module, suppress_events=True)
    ordering.moveObjectToPosition(module.id, position, suppress_events=True)
    return parent[question.id]


def _convert_optional_profiles(root, in_client):
    catalog = getToolByName(root, "portal_catalog")
    todo = collections.deque([root])
    while todo:
        entry = todo.popleft()
        if isinstance(entry, ProfileQuestion):
            type = getattr(entry, "type", None)
            if type is not None:
                del entry.type
            if type == "optional":
                module = _convert_to_module(entry)
                if in_client:
                    survey = aq_parent(module)
                    published = survey.published
                    survey.published = (
                        published[0],
                        published[1],
                        datetime.datetime.now(),
                    )
                else:
                    catalog.indexObject(
                        module, ["portal_type", "meta_type", "object_provides"]
                    )
            continue
        if entry.portal_type not in [
            "euphorie.page",
            "euphorie.module",
            "euphorie.risk",
        ]:
            todo.extend(entry.objectValues())


def convert_optional_profiles(context):
    site = aq_parent(aq_inner(context))
    _convert_optional_profiles(site["sectors"], False)
    _convert_optional_profiles(site["client"], True)


def add_skip_evaluation_to_model(context):
    session = Session()
    inspector = Inspector.from_engine(session.bind)
    columns = [c["name"] for c in inspector.get_columns(model.Risk.__table__.name)]
    if "skip_evaluation" not in columns:
        log.info("Adding skip_evaluation column for risks")
        session.execute(
            "ALTER TABLE %s ADD skip_evaluation BOOL DEFAULT 'f' NOT NULL"
            % model.Risk.__table__.name
        )
        datamanager.mark_changed(session)
