"""
Lesson 25 — Exercise 1: Testing Levels
========================================
Goal: Practice writing UNIT, SUBSYSTEM, and SYSTEM tests on the same code.

Quick refresher:
  - UNIT TEST       → tests ONE method in complete isolation
  - SUBSYSTEM TEST  → tests SEVERAL methods working together
  - SYSTEM TEST     → tests the WHOLE app end-to-end (as a user would)

You'll test the Pet class below. Read it carefully first.
"""


class Pet:
    def __init__(self, name):
        self.name = name
        self.hunger = 50    # 0 = stuffed, 100 = starving
        self.energy = 50    # 0 = exhausted, 100 = energetic
        self.alive = True

    def feed(self):
        """Reduce hunger by 20. Can't feed if dead. Returns True on success."""
        if not self.alive:
            return False
        self.hunger = max(0, self.hunger - 20)
        return True

    def play(self):
        """Drop energy by 15, raise hunger by 10. Refuses if too tired or dead."""
        if not self.alive or self.energy < 15:
            return False
        self.energy -= 15
        self.hunger = min(100, self.hunger + 10)
        return True

    def sleep(self):
        """Restore energy to 100. Can't sleep if dead."""
        if not self.alive:
            return False
        self.energy = 100
        return True

    def tick(self):
        """Time passes. Hunger rises, energy falls. Pet dies if hunger maxes out."""
        self.hunger = min(100, self.hunger + 5)
        self.energy = max(0, self.energy - 5)
        if self.hunger >= 100:
            self.alive = False


# ═══════════════════════════════════════════════════════════════
# TASK A — UNIT TEST
# Test ONE method in isolation. Nothing else runs.
# ═══════════════════════════════════════════════════════════════
# Write test_feed_reduces_hunger() so that it:
#   1. Creates a fresh pet (hunger starts at 50)
#   2. Calls feed() once
#   3. Asserts hunger is now exactly 30
#   4. Prints "✅ unit test passed" if no assertion fires

def test_feed_reduces_hunger():
    # TODO
    pass


# ═══════════════════════════════════════════════════════════════
# TASK B — SUBSYSTEM TEST
# Test multiple methods cooperating. You're checking integration.
# ═══════════════════════════════════════════════════════════════
# Write test_play_drains_then_sleep_restores() so that it:
#   1. Creates a fresh pet (energy starts at 50)
#   2. Calls play() three times — energy should drop to 5
#   3. Asserts the pet REFUSES a fourth play() (returns False)
#   4. Calls sleep() — energy should snap back to 100
#   5. Asserts a fifth play() now works again

def test_play_drains_then_sleep_restores():
    # TODO
    pass


# ═══════════════════════════════════════════════════════════════
# TASK C — SYSTEM TEST
# Simulate a full game session. Treat the Pet as a black box.
# ═══════════════════════════════════════════════════════════════
# Write test_pet_survives_a_day() so that it:
#   1. Creates a fresh pet
#   2. Loops 20 times: tick() happens; if hunger > 70, feed
#   3. Asserts the pet is still alive at the end of 20 ticks

def test_pet_survives_a_day():
    # TODO
    pass


# ═══════════════════════════════════════════════════════════════
# STRETCH — which test caught what?
# After you run all three, write a 1-sentence answer to each:
#   • Which test would have caught a typo in `feed()` (hunger -= 2 instead of 20)?
#   • Which test would have caught a bug where `sleep()` only restored to 80?
#   • Which test would have caught the game crashing after 15 ticks?
# ═══════════════════════════════════════════════════════════════


if __name__ == '__main__':
    print("─── UNIT TEST ───")
    test_feed_reduces_hunger()
    print("─── SUBSYSTEM TEST ───")
    test_play_drains_then_sleep_restores()
    print("─── SYSTEM TEST ───")
    test_pet_survives_a_day()
