from BTrees.OOBTree import OOBTree
from importlib.resources import files
from plone import api
from plone.app import testing
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
from ploneintranet.docconv.client.interfaces import IPreviewSettings
from ploneintranet.docconv.client.utils import PDF_FILENAME
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 Products.CMFCore.indexing import processQueue
from ZODB.blob import Blob
from zope.component import getUtility
from zope.interface import alsoProvides

import unittest


class PloneintranetLibraryLayer(testing.PloneSandboxLayer):
    defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)

    def setUpZope(self, app, configurationContext):
        import ploneintranet.library

        self.loadZCML(package=ploneintranet.library)

        import ploneintranet.search

        self.loadZCML(package=ploneintranet.search)

        import ploneintranet.network

        self.loadZCML(package=ploneintranet.network)

        import ploneintranet.docconv.client

        self.loadZCML(package=ploneintranet.docconv.client)

        import ploneintranet.layout

        self.loadZCML(package=ploneintranet.layout)

    def setUpPloneSite(self, portal):
        self.applyProfile(portal, "ploneintranet.docconv.client:default")
        self.applyProfile(portal, "ploneintranet.library:default")

        with api.env.adopt_user("admin"):
            section = api.content.create(
                type="ploneintranet.library.section",
                title="Human Resources",
                container=portal.library,
            )
            holidays = api.content.create(
                type="ploneintranet.library.folder", title="Holidays", container=section
            )
            generic = api.content.create(
                type="ploneintranet.library.folder", title="Generic", container=section
            )
            dummy_pdf = (
                files("ploneintranet.library.tests") / "data" / "empty.pdf"
            ).read_bytes()
            for container in (holidays, generic):
                for idx in range(5):
                    obj = api.content.create(
                        type="Document", title=str(idx), container=container
                    )
                    blob_files = OOBTree()
                    blob = Blob()
                    with blob.open("w") as bfile:
                        bfile.write(dummy_pdf)
                    blob_files[PDF_FILENAME] = blob
                    IPreviewSettings(obj).blob_files = blob_files


FIXTURE = PloneintranetLibraryLayer()
INTEGRATION_TESTING = testing.IntegrationTesting(
    bases=(FIXTURE,), name="PloneintranetLibraryLayer:Integration"
)


class PloneintranetLibrarySolrLayer(testing.PloneSandboxLayer):
    defaultBases = (SOLR_FIXTURE, FIXTURE)

    def setUpZope(self, app, configurationContext):
        import ploneintranet.search.solr

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

    def setUpPloneSite(self, portal):
        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)
        SOLR_FIXTURE._solr_snapshot()

    def purge_solr(self):
        getUtility(IMaintenance).purge(close_connection=True)

    def testTearDown(self):
        self.purge_solr()


LIBRARY_SOLR_FIXTURE = PloneintranetLibrarySolrLayer()

SOLR_INTEGRATION_TESTING = testing.IntegrationTesting(
    bases=(LIBRARY_SOLR_FIXTURE,), name="PloneintranetLibraryLayer:SolrIntegration"
)


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

    layer = INTEGRATION_TESTING


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

    layer = SOLR_INTEGRATION_TESTING

    def setUp(self):
        """Restore the layer"""
        SOLR_FIXTURE._solr_restore()

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