package com.livingworld.core.simulation;

import com.livingworld.core.services.TimeService;

/**
 * Default implementation of {@link TimeService}.
 * 
 * <p>This service owns an internal {@link LivingWorldCalendar} instance and provides
 * thread-safe access to it by returning defensive copies via {@link #getCalendar()}.</p>
 */
public class DefaultTimeService implements TimeService {

    // ------------------------------------------------------------------
    // Internal state
    // ------------------------------------------------------------------

    /** Internal mutable calendar instance. Used for tracking simulation time. */
    private final LivingWorldCalendar internalCalendar;

    // ------------------------------------------------------------------
    // Constructors
    // ------------------------------------------------------------------

    /**
     * Creates a new {@code DefaultTimeService} with a calendar starting at epoch.
     * 
     * <p>The initial state is: day=1, month=1, year=1, simulationTick=0.</p>
     */
    public DefaultTimeService() {
        this.internalCalendar = new LivingWorldCalendar();
    }

    // ------------------------------------------------------------------
    // TimeService interface implementation
    // ------------------------------------------------------------------

    @Override
    public long getSimulationTick() {
        return internalCalendar.getSimulationTick();
    }

    @Override
    public LivingWorldCalendar getCalendar() {
        // Return a defensive copy to prevent external mutation of internal state
        return internalCalendar.copy();
    }

    @Override
    public void advanceSimulationTick() {
        internalCalendar.advanceTicks(1);
    }

    @Override
    public void advanceSimulationTicks(long ticks) {
        if (ticks < 0L) {
            throw new IllegalArgumentException("ticks must be >= 0, got: " + ticks);
        }
        internalCalendar.advanceTicks(ticks);
    }
}
