from plone import api
from ploneintranet.search.solr.adapters import SearchResponse
from ploneintranet.search.solr.adapters import SearchResult
from ploneintranet.search.solr.interfaces import IMaintenance
from ploneintranet.search.solr.solr_search import SiteSearch
from ploneintranet.search.solr.testing import FunctionalTestCaseWithDummyContent
from ploneintranet.search.solr.testing import IntegrationTestCase
from Products.CMFCore.indexing import processQueue
from zope.component import getUtility


class TestSolrSearchResult(IntegrationTestCase):
    """Test the SearchResult class."""

    def setUp(self):
        super().setUp()
        self.portal = self.layer["portal"]

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

    def test_get_object(self):
        folder = api.content.create(
            container=self.portal,
            type="Folder",
            id="restricted-folder",
            title="Restricted Folder",
        )
        api.content.transition(obj=folder, to_state="private")
        event = api.content.create(
            container=folder, type="Event", id="public-event", title="Public Event"
        )
        api.content.transition(obj=event, to_state="published")
        self.solr_commit()

        util = SiteSearch()
        with api.env.adopt_user("icarus"):
            self.assertIn(
                event,
                [res.getObject() for res in util.query("Public")],
                msg="Cannot get object from search result",
            )


class TestSearchResponse(FunctionalTestCaseWithDummyContent):

    def test_search_response_len(self):
        """Test the length of the SearchResponse object.

        The length is the number of results in the current batch.

        We also have an attribute `total_results` which is the total number
        of results matching the query.
        """
        util = SiteSearch()

        # We search for something that we can find:
        results: SearchResponse = util.query(self.portal.Title())
        self.assertEqual(len(results), 1)
        self.assertEqual(results.total_results, 1)

        # Searching for something with a `-` in it reverses the search
        # If we look for something that is not there, we get all the results
        results: SearchResponse = util.query("-four_zero_four")
        self.assertEqual(len(results), 7)
        self.assertEqual(results.total_results, 7)

        # We can change the batch size with the step parameter, this makes
        # the length of the results smaller, but the total_results remains
        # the same
        results: SearchResponse = util.query("-four_zero_four", step=5)
        self.assertEqual(len(results), 5)
        self.assertEqual(results.total_results, 7)

    def test_search_response_get_item(self):
        util = SiteSearch()
        results: SearchResponse = util.query("-four_zero_four")
        results_tuple = tuple(results)

        result: SearchResult = results[3]
        self.assertIsInstance(result, SearchResult)
        self.assertEqual(results_tuple[3].context, results[3].context)
