package com.livingworld.modules;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.List;

import org.junit.jupiter.api.Test;

import com.livingworld.data.serialization.PersistenceReader;
import com.livingworld.data.serialization.PersistenceWriter;
import com.livingworld.events.LivingWorldEvent;
import com.livingworld.regions.Region;

class ModuleRegistryTest {

    @Test
    void preservesRegistrationOrder() {
        ModuleRegistry registry = new ModuleRegistry();
        registry.register(new StubModule("soil"));
        registry.register(new StubModule("water"));
        registry.register(new StubModule("pollution"));

        assertEquals(
                List.of("soil", "water", "pollution"),
                registry.getEnabledModules().stream().map(SimulationModule::getModuleId).toList());
    }

    @Test
    void rejectsMismatchedModuleAndMetadataIds() {
        ModuleRegistry registry = new ModuleRegistry();

        assertThrows(IllegalArgumentException.class,
                () -> registry.register(new StubModule("soil") {
                    @Override
                    public ModuleMetadata getMetadata() {
                        return metadata("water");
                    }
                }));
    }

    private static class StubModule implements SimulationModule {
        private final String id;

        private StubModule(String id) {
            this.id = id;
        }

        @Override public String getModuleId() { return id; }
        @Override public ModuleMetadata getMetadata() { return metadata(id); }
        @Override public void initialize(ModuleContext context) {}
        @Override public void onServerStarted(ServerContext context) {}
        @Override public void createDefaultRegionData(Region region) {}
        @Override public ModuleUpdateResult updateRegion(RegionUpdateContext context) {
            return ModuleUpdateResult.noChange();
        }
        @Override public void onLivingWorldEvent(LivingWorldEvent event) {}
        @Override public void saveModuleData(PersistenceWriter writer) {}
        @Override public void loadModuleData(PersistenceReader reader) {}
        @Override public void shutdown() {}
    }

    private static ModuleMetadata metadata(String id) {
        return new ModuleMetadata(
                id, id, "1.0.0", "", "1",
                List.of(), List.of(), true, true, false);
    }
}
