from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
from plone.app.testing import applyProfile
from plone.app.testing import FunctionalTesting
from plone.app.testing import IntegrationTesting
from plone.app.testing import PloneSandboxLayer
from plone.app.testing import setRoles
from plone.app.testing import TEST_USER_ID
from plone.testing import Layer
from plone.testing import zca
from plone.testing import zope as zope_testing
from zope.configuration import xmlconfig

import six
import time


def tearDownContainer(container):
    from ploneintranet.microblog.statuscontainer import STATUSQUEUE

    # stop the thread timer
    try:
        container._v_timer.cancel()
        time.sleep(1)  # allow for thread cleanup
    except AttributeError:
        pass

    # we have an in-memory queue, purge it
    while True:
        try:
            STATUSQUEUE.get(block=False)
        except six.moves.queue.Empty:
            break


class PloneIntranetMicroblog(PloneSandboxLayer):

    defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)

    def setUpZope(self, app, configurationContext):
        # Load ZCML for this package
        import ploneintranet.microblog

        xmlconfig.file(
            "configure.zcml", ploneintranet.microblog, context=configurationContext
        )
        # no content updates, except on
        #   PLONEINTRANET_MICROBLOG_CONTENTUPDATES_TESTING
        # tests run sync, except for test_statuscontainer_queued
        import ploneintranet.activitystream

        xmlconfig.file(
            "configure.zcml", ploneintranet.activitystream, context=configurationContext
        )
        import ploneintranet.attachments

        self.loadZCML(package=ploneintranet.attachments)
        zope_testing.installProduct(app, "ploneintranet.attachments")

    def setUpPloneSite(self, portal):
        applyProfile(portal, "ploneintranet.microblog:default")
        setRoles(portal, TEST_USER_ID, ["Manager"])

        # We need ploneintranet.userprofile for ``pas_view``.
        # But then also ploneintranet.notifications subscribers are registered.
        # For this to work, we need to install the ploneintranet.notifications
        # browser layer. So then:
        applyProfile(portal, "ploneintranet.notifications:default")


PLONEINTRANET_MICROBLOG_FIXTURE = PloneIntranetMicroblog()
PLONEINTRANET_MICROBLOG_INTEGRATION_TESTING = IntegrationTesting(
    bases=(PLONEINTRANET_MICROBLOG_FIXTURE,), name="PloneIntranetMicroblog:Integration"
)
PLONEINTRANET_MICROBLOG_FUNCTIONAL_TESTING = FunctionalTesting(
    bases=(PLONEINTRANET_MICROBLOG_FIXTURE,), name="PloneIntranetMicroblog:Functional"
)


class PloneIntranetMicroblogSubcriber(Layer):

    defaultBases = (PLONEINTRANET_MICROBLOG_FIXTURE,)

    def __init__(self, zcml_file):
        super().__init__()
        self.zcml_file = zcml_file

    def setUp(self):
        self["configurationContext"] = context = zca.stackConfigurationContext(
            self.get("configurationContext")
        )
        import ploneintranet.microblog

        xmlconfig.file(self.zcml_file, ploneintranet.microblog, context=context)

    def setUpPloneSite(self, portal):
        # Remove the memcached counter.
        # This is needed to prevent the same cache key to be used in different tests
        if hasattr(portal.acl_users, "_memcachedcounter"):
            delattr(portal.acl_users, "_memcachedcounter")

    def tearDown(self):
        del self["configurationContext"]


PLONEINTRANET_MICROBLOG_PORTAL_SUBSCRIBER_FIXTURE = PloneIntranetMicroblogSubcriber(
    "tests/testing_portal_subscriber.zcml"
)
PLONEINTRANET_MICROBLOG_PORTAL_SUBSCRIBER_INTEGRATION_TESTING = IntegrationTesting(
    bases=(PLONEINTRANET_MICROBLOG_PORTAL_SUBSCRIBER_FIXTURE,),
    name="PloneIntranetMicroblogPortalSubscriber:Integration",
)

PLONEINTRANET_MICROBLOG_REQUEST_SUBSCRIBER_FIXTURE = PloneIntranetMicroblogSubcriber(
    "tests/testing_request_subscriber.zcml"
)
PLONEINTRANET_MICROBLOG_REQUEST_SUBSCRIBER_INTEGRATION_TESTING = IntegrationTesting(
    bases=(PLONEINTRANET_MICROBLOG_REQUEST_SUBSCRIBER_FIXTURE,),
    name="PloneIntranetMicroblogRequestSubscriber:Integration",
)

PLONEINTRANET_MICROBLOG_CONTENTUPDATES_FIXTURE = PloneIntranetMicroblogSubcriber(
    "subscribers.zcml"
)
PLONEINTRANET_MICROBLOG_CONTENTUPDATES_TESTING = IntegrationTesting(
    bases=(PLONEINTRANET_MICROBLOG_CONTENTUPDATES_FIXTURE,),
    name="PloneIntranetMicroblogContentupdatesSubscriber:Functional",
)
