# Service Pattern Quick Reference

## The Golden Rules

1. ✅ **Agents are data containers** - No behavior methods, only state
2. ✅ **Services contain all behavior** - All logic goes in services
3. ✅ **Services schedule events** - Never have agents schedule themselves
4. ✅ **Agents are arguments** - Services act ON agents, not WITH agents

## Quick Examples

### ❌ DON'T: Agent-Centric (Old Way)
```python
class Student(Agent):
    def __init__(self, world):
        self.world = world  # Circular dependency!

    def make_friend(self, other):
        self.world.friendship_manager.register(...)  # Agent knows about world

    def misbehave(self):
        # Complex behavior logic in agent
        if self.mood < 0.5:
            ...

# Scheduling
schedule.add_event(step, lambda: student.misbehave())  # Agent does action
```

### ✅ DO: Service-Centric (New Way)
```python
class Student(Agent):
    """Just data, no behavior."""
    def __init__(self, age, race):
        self.age = age
        self.race = race
        self.mood = 0.5

class DisciplineService(Service):
    """All behavior logic here."""
    def evaluate_misbehavior(self, student, teachers):
        # All logic in service
        if student.mood < 0.5:
            ...

    def schedule_evaluations(self, schedule, students, teachers, start, end):
        """Service schedules its own events."""
        for step in range(start, end):
            schedule.add_event(
                step, lambda s=student: self.evaluate_misbehavior(s, teachers)
            )

# In World.setup_events():
discipline_service.schedule_evaluations(schedule, students, teachers, 1, 1000)
```

## Creating a New Service

### 1. Define the Service
```python
from layer1_core.managers.service import Service

class MyService(Service):
    def __init__(self, service_id: str = "my_service"):
        super().__init__(service_id)

    def do_action(self, agent: Agent, other_params):
        """Service method that acts on agents."""
        # Modify agent state
        agent.some_attribute = new_value

    def schedule_events(self, schedule, agents, start, end):
        """Service schedules its own events."""
        for step in range(start, end):
            agent = choice(agents)
            schedule.add_event(
                step, lambda a=agent: self.do_action(a, params)
            )
```

### 2. Register in World
```python
class MyWorld(WorldBuilder):
    def __init__(self, params):
        super().__init__(params)  # Creates ServiceRegistry

        # Create service
        self.my_service = MyService("my_service")

        # Register service
        self.services.register(self.my_service)

    def setup_events(self):
        # Service schedules itself
        self.my_service.schedule_events(self.schedule, agents, 1, 1000)
```

## Pattern Checklist

When adding new behavior, ask:

- [ ] Is the logic in a Service, not in an Agent?
- [ ] Are Agents passed as arguments to Service methods?
- [ ] Does the Service schedule its own events?
- [ ] Are Agents just data containers?
- [ ] Is the Service registered in the ServiceRegistry?
- [ ] Does WorldBuilder delegate scheduling to Services?

If all yes → You're following the pattern! ✅

## Common Patterns

### Pattern 1: Service acts on single agent
```python
class CounselingService(Service):
    def provide_counseling(self, student: Student, counselor: Counselor):
        """Service acts on both agents."""
        improvement = random() * counselor.attitude
        student.mood += improvement * 0.1
```

### Pattern 2: Service acts on multiple agents
```python
class FriendshipManager(Service):
    def make_friend(self, student1: Student, student2: Student):
        """Service creates relationship between agents."""
        friendship = Friendship(student1, student2, strength=0.5)
        self.register_friendship(friendship)
```

### Pattern 3: Service schedules recurring events
```python
class HousingService(Service):
    def schedule_monthly_evaluations(self, schedule, students):
        """Service schedules periodic events."""
        for month in range(1, 13):
            step = month * 30  # Every 30 steps
            for student in students:
                schedule.add_event(
                    step,
                    lambda s=student: self.evaluate_housing(s)
                )
```

### Pattern 4: Service uses other services
```python
class AdvancedDisciplineService(Service):
    def record_severe_misbehavior(self, student, teacher):
        # Use this service's logic
        self.record_misbehavior(student, teacher)

        # Get another service
        if len(student.disciplinaryRecord) > 5:
            counseling = self.get_world().services.get_by_type(CounselingService)
            counseling.schedule_session(student)
```

## Migration Checklist

Migrating from agent-centric to service-centric?

1. [ ] Create Service class
2. [ ] Move behavior methods from Agent to Service
3. [ ] Update method signatures to take agents as parameters
4. [ ] Strip Agent down to just state attributes
5. [ ] Create `schedule_events()` method in Service
6. [ ] Register Service in World.__init__()
7. [ ] Call Service.schedule_events() in World.setup_events()
8. [ ] Remove any World/Service references from Agents
9. [ ] Run tests!

## Files to Reference

- **Architecture**: `demos/school_demo/SERVICE_CENTRIC_ARCHITECTURE.md`
- **Core Service**: `src/layer1_core/managers/service.py`
- **Example Services**: `demos/school_demo/src/schoolServices.py`
- **Example World**: `demos/school_demo/src/schoolWorld.py`
- **Example Agents**: `demos/school_demo/src/individual.py`