from collective.mustread.testing import tempDb
from plone import api
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.zope import WSGI_SERVER_FIXTURE
from ploneintranet.news.browser.interfaces import INewsContentLayer
from ploneintranet.notifications.testing import SQL_FIXTURE
from ploneintranet.search.interfaces import IPloneintranetSearchLayer
from ploneintranet.search.solr.interfaces import IMaintenance
from ploneintranet.search.solr.testing import load_solr_zcml
from ploneintranet.search.solr.testing import SOLR_FIXTURE
from ploneintranet.userprofile.testing import PLONEINTRANET_USERPROFILE_FIXTURE
from Products.CMFCore.indexing import processQueue
from zope.component import getUtility
from zope.interface import alsoProvides

import unittest


class PloneintranetNewsLayer(PloneSandboxLayer):

    defaultBases = (
        SOLR_FIXTURE,
        PLONEINTRANET_USERPROFILE_FIXTURE,
        SQL_FIXTURE,
    )

    def solr_sync(self, portal):
        """Sync the portal content in to Solr"""
        with api.env.adopt_user("admin"):
            request = portal.REQUEST
            alsoProvides(request, IPloneintranetSearchLayer)
            view = api.content.get_view("solr-maintenance", portal, request)
            view.sync(close_connection=True)

    def setUpZope(self, app, configurationContext):

        import ploneintranet.search.solr

        self.loadZCML(package=ploneintranet.search.solr)
        load_solr_zcml()

        import ploneintranet.notifications.tests

        self.loadZCML(package=ploneintranet.notifications.tests)

        import ploneintranet.news

        self.loadZCML(package=ploneintranet.news)

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

        self.solr_sync(portal)
        SOLR_FIXTURE._solr_snapshot()

    def testSetUp(self):
        SOLR_FIXTURE._solr_restore()


PLONEINTRANET_NEWS_FIXTURE = PloneintranetNewsLayer()
INTEGRATION_TESTING = IntegrationTesting(
    bases=(PLONEINTRANET_NEWS_FIXTURE,), name="PloneintranetNewsLayer:Integration"
)
FUNCTIONAL_TESTING = FunctionalTesting(
    bases=(PLONEINTRANET_NEWS_FIXTURE, WSGI_SERVER_FIXTURE),
    name="PloneintranetNewsLayer:Functional",
)


class IntegrationTestCase(unittest.TestCase):
    """Base class for integration tests."""

    layer = INTEGRATION_TESTING

    def setUp(self):
        self.app = self.layer["app"]
        self.portal = self.layer["portal"]
        alsoProvides(self.layer["request"], INewsContentLayer)
        self.request = self.layer["request"].clone()

    def solr_commit(self):
        """On integration tests we need to commit on solr before searching"""
        processQueue()
        getUtility(IMaintenance).connection.commit()


class FunctionalTestCase(IntegrationTestCase):
    """Base class for functional tests."""

    layer = FUNCTIONAL_TESTING

    def setUp(self):
        super().setUp()
        self.db = tempDb()  # auto teardown via __del__
