from datetime import datetime, timedelta, timezone

from django.test import TestCase
from freezegun import freeze_time

from rest_framework_simplejwt.utils import (
    aware_utcnow,
    datetime_from_epoch,
    datetime_to_epoch,
    format_lazy,
    make_utc,
)


class TestMakeUtc(TestCase):
    def test_it_should_return_the_correct_values(self):
        # It should make a naive datetime into an aware, utc datetime if django
        # is configured to use timezones and the datetime doesn't already have
        # a timezone

        # Naive datetime
        dt = datetime(year=1970, month=12, day=1)

        with self.settings(USE_TZ=False):
            dt = make_utc(dt)
            self.assertTrue(dt.tzinfo is None)

        with self.settings(USE_TZ=True):
            dt = make_utc(dt)
            self.assertTrue(dt.tzinfo is not None)
            self.assertEqual(dt.utcoffset(), timedelta(seconds=0))


class TestAwareUtcnow(TestCase):
    def test_it_should_return_the_correct_value(self):
        now = datetime.now(tz=timezone.utc).replace(tzinfo=None)

        with freeze_time(now):
            # Should return aware utcnow if USE_TZ == True
            with self.settings(USE_TZ=True):
                self.assertEqual(now.replace(tzinfo=timezone.utc), aware_utcnow())

            # Should return naive utcnow if USE_TZ == False
            with self.settings(USE_TZ=False):
                self.assertEqual(now, aware_utcnow())


class TestDatetimeToEpoch(TestCase):
    def test_it_should_return_the_correct_values(self):
        self.assertEqual(datetime_to_epoch(datetime(year=1970, month=1, day=1)), 0)
        self.assertEqual(
            datetime_to_epoch(datetime(year=1970, month=1, day=1, second=1)), 1
        )
        self.assertEqual(
            datetime_to_epoch(datetime(year=2000, month=1, day=1)), 946684800
        )


class TestDatetimeFromEpoch(TestCase):
    def test_it_should_return_the_correct_values(self):
        with self.settings(USE_TZ=False):
            self.assertEqual(
                datetime_from_epoch(0), datetime(year=1970, month=1, day=1)
            )
            self.assertEqual(
                datetime_from_epoch(1), datetime(year=1970, month=1, day=1, second=1)
            )
            self.assertEqual(
                datetime_from_epoch(946684800),
                datetime(year=2000, month=1, day=1),
                946684800,
            )

        with self.settings(USE_TZ=True):
            self.assertEqual(
                datetime_from_epoch(0), make_utc(datetime(year=1970, month=1, day=1))
            )
            self.assertEqual(
                datetime_from_epoch(1),
                make_utc(datetime(year=1970, month=1, day=1, second=1)),
            )
            self.assertEqual(
                datetime_from_epoch(946684800),
                make_utc(datetime(year=2000, month=1, day=1)),
            )


class TestFormatLazy(TestCase):
    def test_it_should_work(self):
        obj = format_lazy("{} {}", "arst", "zxcv")

        self.assertNotIsInstance(obj, str)
        self.assertEqual(str(obj), "arst zxcv")
