package com.livingworld.config;

/**
 * Configuration class for simulation parameters.
 * 
 * This class holds plain integer and boolean fields that control how the
 * living world simulation behaves at runtime.  It is intentionally free of
 * any Minecraft or NeoForge dependencies so it can be instantiated in pure
 * JUnit tests.
 */
public final class SimulationConfig {

    // ------------------------------------------------------------------
    // Field defaults
    // ------------------------------------------------------------------

    /** Size of a region in chunks (must be >= 1). */
    private int regionSizeChunks = 8;

    /** Interval between simulation cycles, in game ticks (must be >= 1). */
    private int simulationIntervalTicks = 100;

    /** Maximum number of regions processed per cycle (must be >= 1). */
    private int maxRegionsPerCycle = 50;

    /** Maximum time budget for a single cycle in milliseconds (must be >= 1). */
    private int maxMillisecondsPerCycle = 25;

    /** Emergency stop threshold when simulation is overrunning (>= maxMillisecondsPerCycle). */
    private int emergencyStopMilliseconds = 40;

    /** Enable diagnostic / debug commands. */
    private boolean enableDebugCommands = true;

    /** Enable the built-in profiler. */
    private boolean enableProfiler = true;

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

    /** Default constructor – uses all default values. */
    public SimulationConfig() {
        // Intentionally empty; fields are initialised at declaration.
    }

    // ------------------------------------------------------------------
    // Getters
    // ------------------------------------------------------------------

    public int getRegionSizeChunks() {
        return regionSizeChunks;
    }

    public int getSimulationIntervalTicks() {
        return simulationIntervalTicks;
    }

    public int getMaxRegionsPerCycle() {
        return maxRegionsPerCycle;
    }

    public int getMaxMillisecondsPerCycle() {
        return maxMillisecondsPerCycle;
    }

    public int getEmergencyStopMilliseconds() {
        return emergencyStopMilliseconds;
    }

    public boolean isEnableDebugCommands() {
        return enableDebugCommands;
    }

    public boolean isEnableProfiler() {
        return enableProfiler;
    }

    // ------------------------------------------------------------------
    // Setters (package-private for testability)
    // ------------------------------------------------------------------

    public void setRegionSizeChunks(final int regionSizeChunks) {
        this.regionSizeChunks = regionSizeChunks;
    }

    public void setSimulationIntervalTicks(final int simulationIntervalTicks) {
        this.simulationIntervalTicks = simulationIntervalTicks;
    }

    public void setMaxRegionsPerCycle(final int maxRegionsPerCycle) {
        this.maxRegionsPerCycle = maxRegionsPerCycle;
    }

    public void setMaxMillisecondsPerCycle(final int maxMillisecondsPerCycle) {
        this.maxMillisecondsPerCycle = maxMillisecondsPerCycle;
    }

    public void setEmergencyStopMilliseconds(final int emergencyStopMilliseconds) {
        this.emergencyStopMilliseconds = emergencyStopMilliseconds;
    }

    public void setEnableDebugCommands(final boolean enableDebugCommands) {
        this.enableDebugCommands = enableDebugCommands;
    }

    public void setEnableProfiler(final boolean enableProfiler) {
        this.enableProfiler = enableProfiler;
    }

    // ------------------------------------------------------------------
    // Validation
    // ------------------------------------------------------------------

    /**
     * Validates every field against its constraints.  Throws
     * {@link IllegalArgumentException} with a descriptive message if any
     * constraint is violated.
     *
     * @throws IllegalArgumentException if validation fails
     */
    public void validate() {
        if (regionSizeChunks < 1) {
            throw new IllegalArgumentException(
                "regionSizeChunks must be >= 1, got: " + regionSizeChunks);
        }

        if (simulationIntervalTicks < 1) {
            throw new IllegalArgumentException(
                "simulationIntervalTicks must be >= 1, got: " + simulationIntervalTicks);
        }

        if (maxRegionsPerCycle < 1) {
            throw new IllegalArgumentException(
                "maxRegionsPerCycle must be >= 1, got: " + maxRegionsPerCycle);
        }

        if (maxMillisecondsPerCycle < 1) {
            throw new IllegalArgumentException(
                "maxMillisecondsPerCycle must be >= 1, got: " + maxMillisecondsPerCycle);
        }

        if (emergencyStopMilliseconds < maxMillisecondsPerCycle) {
            throw new IllegalArgumentException(
                "emergencyStopMilliseconds (" + emergencyStopMilliseconds
                    + ") must be >= maxMillisecondsPerCycle (" + maxMillisecondsPerCycle + ")");
        }
    }

    // ------------------------------------------------------------------
    // Utility / Debug
    // ------------------------------------------------------------------

    @Override
    public String toString() {
        return "SimulationConfig{"
            + "regionSizeChunks=" + regionSizeChunks
            + ", simulationIntervalTicks=" + simulationIntervalTicks
            + ", maxRegionsPerCycle=" + maxRegionsPerCycle
            + ", maxMillisecondsPerCycle=" + maxMillisecondsPerCycle
            + ", emergencyStopMilliseconds=" + emergencyStopMilliseconds
            + ", enableDebugCommands=" + enableDebugCommands
            + ", enableProfiler=" + enableProfiler
            + '}';
    }
}