from fsrs import *
from datetime import datetime, UTC
import pytest


def print_scheduling_cards(scheduling_cards):
    print("again.card:", scheduling_cards[Rating.Again].card.__dict__)
    print("again.review_log:", scheduling_cards[Rating.Again].review_log.__dict__)
    print("hard.card:", scheduling_cards[Rating.Hard].card.__dict__)
    print("hard.review_log:", scheduling_cards[Rating.Hard].review_log.__dict__)
    print("good.card:", scheduling_cards[Rating.Good].card.__dict__)
    print("good.review_log:", scheduling_cards[Rating.Good].review_log.__dict__)
    print("easy.card:", scheduling_cards[Rating.Easy].card.__dict__)
    print("easy.review_log:", scheduling_cards[Rating.Easy].review_log.__dict__)
    print()


class TestPyFSRS:

    def test_repeat(self):
        f = FSRS()
        f.p.w = (
            1.14,
            1.01,
            5.44,
            14.67,
            5.3024,
            1.5662,
            1.2503,
            0.0028,
            1.5489,
            0.1763,
            0.9953,
            2.7473,
            0.0179,
            0.3105,
            0.3976,
            0.0,
            2.0902,
        )
        card = Card()
        now = datetime(2022, 11, 29, 12, 30, 0, 0, tzinfo=UTC)
        scheduling_cards = f.repeat(card, now)
        print_scheduling_cards(scheduling_cards)

        ratings = (
            Rating.Good,
            Rating.Good,
            Rating.Good,
            Rating.Good,
            Rating.Good,
            Rating.Good,
            Rating.Again,
            Rating.Again,
            Rating.Good,
            Rating.Good,
            Rating.Good,
            Rating.Good,
            Rating.Good,
        )
        ivl_history = []

        for rating in ratings:
            card = scheduling_cards[rating].card
            ivl = card.scheduled_days
            ivl_history.append(ivl)
            now = card.due
            scheduling_cards = f.repeat(card, now)
            print_scheduling_cards(scheduling_cards)

        print(ivl_history)
        assert ivl_history == [0, 5, 16, 43, 106, 236, 0, 0, 12, 25, 47, 85, 147]

    def test_datetime(self):

        f = FSRS()
        card = Card()

        # new cards should be due immediately after creation
        assert datetime.now(UTC) >= card.due

        # comparing timezone aware cards with deprecated datetime.utcnow() should raise a TypeError
        with pytest.raises(TypeError):
            datetime.now() >= card.due

        # repeating a card with a non-utc, non-timezone-aware datetime object should raise a Value Error
        with pytest.raises(ValueError):
            f.repeat(card, datetime(2022, 11, 29, 12, 30, 0, 0))

        # repeat a card with rating good before next tests
        scheduling_cards = f.repeat(card, datetime.now(UTC))
        card = scheduling_cards[Rating.Good].card

        # card object's due and last_review attributes must be timezone aware and UTC
        assert card.due.tzinfo == UTC
        assert card.last_review.tzinfo == UTC
        # card object's due datetime should be later than its last review
        assert card.due >= card.last_review
