import datetime
import pytz

from .helpers import APITestCase

from sermonaudio.node.requests import Node


class WebcastStatsTests(APITestCase):
    start_as_datetime = datetime.datetime.strptime("2020-01-01", "%Y-%m-%d").astimezone(tz=pytz.UTC)
    end_as_datetime = datetime.datetime.strptime("2020-01-31", "%Y-%m-%d").astimezone(tz=pytz.UTC)

    date_range_params = {
        "broadcaster_id": "faith",
        "start_time": int(start_as_datetime.timestamp()),
        "end_time": int(end_as_datetime.timestamp()),
    }

    nonwebcast_broadcaster_id: str = "allan"

    # This webcast belongs to Cornerstone in RI.
    cornerstone_webcast_id: int = 231137

    def test_nonwebcast_broadcaster_has_no_results(self):
        """Tests that a broadcaster who does not webcast will see no results."""

        nonwebcast_params = self.date_range_params.copy()
        nonwebcast_params["broadcaster_id"] = self.nonwebcast_broadcaster_id

        page = Node.get_webcasts(**nonwebcast_params)

        # We should get no results for a broadcaster who has no webcasts.
        self.assertFalse(page.results)

    def test_get_webcast_list(self):
        page = Node.get_webcasts(**self.date_range_params)

        self.assertTrue(page.results)

        for webcast in page.results:
            self.assertIsNotNone(webcast.webcast_id)

            self.assertEqual(webcast.broadcaster_id, self.date_range_params["broadcaster_id"])

            # The start time must be in the date range. (We only use start time
            # for date range, and ignore end time.)
            self.assertGreaterEqual(webcast.start_time, self.start_as_datetime)
            self.assertLessEqual(webcast.start_time, self.end_as_datetime)

            # These two fields should be non-negative.
            self.assertGreaterEqual(webcast.peak_listener_count, 0)
            self.assertGreaterEqual(webcast.total_tune_in_count, 0)

    def test_get_webcast_totals(self):
        totals = Node.get_webcast_stats_totals(**self.date_range_params)

        # This endpoint should return something.
        self.assertIsNotNone(totals)

        # We should have gotten the same dates back.
        self.assertEqual(totals.start_time, self.start_as_datetime)
        self.assertEqual(totals.end_time, self.end_as_datetime)

        # These two fields should be non-negative.
        self.assertGreater(totals.max_peak_listener_count, 0)
        self.assertGreater(totals.avg_total_tune_in_count, 0)

        # The webcast should have zero or more total views, and the total
        # should not be less than the average.
        self.assertGreaterEqual(totals.total_webcast_views, 0)
        self.assertGreaterEqual(totals.total_webcast_views, totals.avg_total_tune_in_count)

        # We should get some cumulative stats back, and we can assert that we
        # did not get a webcast_id (since these stats aren't for a webcast) and
        # that we got locations back, and the totals are non-negagive.
        self.assertIsNotNone(totals.cumulative_stats)
        self.assertIsNone(totals.cumulative_stats.webcast_id)
        self.assertIsNotNone(totals.cumulative_stats.locations)
        # Faith ought to have US viewers.
        self.assertTrue("US" in totals.cumulative_stats.locations)

        self.assertGreater(totals.cumulative_stats.total_countries, 0)

    def test_get_webcast_detail(self):
        """Tests that we can get webcast details for a webcast_id."""

        webcast_stats = Node.get_webcast_stats(self.cornerstone_webcast_id)

        self.assertEqual(webcast_stats.webcast_id, self.cornerstone_webcast_id)

        # This webcast's broadcaster is in RI.
        self.assertTrue("US" in webcast_stats.locations)
        self.assertTrue("RI" in webcast_stats.locations["US"]["regions"])

        self.assertGreater(webcast_stats.total_countries, 0)

    def test_get_single_webcast(self):
        """Tests getting a single webcast by webcast ID.

        We never delete webcasts from the log table, so this test should be stable.
        """

        webcast = Node.get_webcast(broadcaster_id="faith", webcast_id=253677)

        # We should get back what we asked for.
        self.assertEqual(webcast.broadcaster_id, "faith")
        self.assertEqual(webcast.webcast_id, 253677)

        # These fields are generated by the API and should always exist.
        self.assertIsNotNone(webcast.media.audio)
        self.assertIsNotNone(webcast.media.video)
